我有一个结构如下example_df所示的数据集:
example_df = pd.DataFrame({'measurement_id': np.concatenate([[0] * 300, [1] * 300]),\n 'min': np.concatenate([np.repeat(range(0, 30), 10), \n np.repeat(range(0, 30), 10)]),\n 'grp': list(np.repeat(['A', 'B'], 5)) * 60,\n 'grp2': list(np.random.choice([0, 1, 2], 10)) * 60,\n 'obj': np.array(list(range(0, 10)) * 60),\n 'x': np.random.normal(0.0, 10.0, 600),\n 'y': np.random.normal(50.0, 40.0, 600)})\nRun Code Online (Sandbox Code Playgroud)\n\n我还有一个函数,它将点组列表作为输入并执行一些计算。我想准备数据并在分组数据框中创建点列表列表。
\n\n我目前的解决方案如下:
\n\ndef df_to_points(df):\n points = []\n for index, row in df.iterrows():\n points.append(tuple(row))\n return(points)\n\nres = example_df \\\n .groupby(['measurement_id', 'min', 'grp']) \\\n .apply(lambda x: [df_to_points(g[['x', 'y']]) for _, g in x.groupby('grp2')])\n\nres.head(5)\nmeasurement_id min grp\n0 0 A [[(7.435996920897324, 63.64844826366264), (-9....\n 1 B [[(-10.213911323779579, 108.64263032884301), (...\n 2 A [[(6.004534743892181, 38.11898691750269), (12....\n 3 B [[(-11.486905682289555, 68.26172126981378), (-...\n 4 A [[(7.5612638943199295, 28.756743327333556), (-...\nRun Code Online (Sandbox Code Playgroud)\n\n系列的每一行res看起来像这样:
[[(7.435996920897324, 63.64844826366264),\n (-9.722976872232584, 11.831678494223155),\n (10.809492206072777, 82.9238481225157),\n (-7.918248246978473, 58.46902598333271)],\n [(6.270634566510545, 59.10653240815831),\n (-5.765185730532471, 22.232739287056663),\n (-13.129531349093371, 85.02932179274353)],\n [(0.6686875099768917, 60.634711491838786),\n (-7.373072676442981, 30.897262347426693),\n (-11.489744246260528, 6.834296232736001)]] \nRun Code Online (Sandbox Code Playgroud)\n\n问题是我原来的 DataFrame 有几百万行,感觉这个解决方案可以从一些优化中受益。
\n\n该示例的当前运行时间是:
\n\n%timeit res = example_df \\\n .groupby(['measurement_id', 'min', 'grp']) \\\n .apply(lambda x: [df_to_points(g[['x', 'y']]) for _, g in x.groupby('grp2')])\n289 ms \xc2\xb1 1.36 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 1 loop each)\nRun Code Online (Sandbox Code Playgroud)\n\n因此,我的问题是:
\n\nnumpy提高性能吗?@Edit:一个示例,其中包含由以下定义的组内的各种数量的对象grp
example_df2 = pd.DataFrame({'measurement_id': np.concatenate([[0] * 300, [1] * 300]),\n 'min': np.concatenate([np.repeat(range(0, 30), 10), \n np.repeat(range(0, 30), 10)]),\n 'grp': list(np.repeat(['A', 'B', 'C'], [4, 4, 2])) * 60,\n 'grp2': list(np.random.choice([0, 1, 2], 10)) * 60,\n 'obj': np.array(list(range(0, 10)) * 60),\n 'x': np.random.normal(0.0, 10.0, 600),\n 'y': np.random.normal(50.0, 40.0, 600)})\nRun Code Online (Sandbox Code Playgroud)\n
您可以将整个数据帧转换为 numpy 数组,然后再仅使用array = np.array(df). 它肯定会提高性能。您还可以使用多线程模块来并行处理并提高性能。您还可以使用 pandas .apply()而不是使用.iterrows()