在每组 Pandas 数据框中创建点列表

Xau*_*ume 5 python pandas

我有一个结构如下example_df所示的数据集:

\n\n
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)})\n
Run Code Online (Sandbox Code Playgroud)\n\n

我还有一个函数,它将点组列表作为输入并执行一些计算。我想准备数据并在分组数据框中创建点列表列表。

\n\n

我目前的解决方案如下:

\n\n
def 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), (-...\n
Run Code Online (Sandbox Code Playgroud)\n\n

系列的每一行res看起来像这样:

\n\n
[[(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)]] \n
Run 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)\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,我的问题是:

\n\n
    \n
  1. 用多维数组替换元组列表会numpy提高性能吗?
  2. \n
  3. 为了提高速度是否应该避免任何重大瓶颈?
  4. \n
\n\n

@Edit:一个示例,其中包含由以下定义的组内的各种数量的对象grp

\n\n
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)})\n
Run Code Online (Sandbox Code Playgroud)\n

Gui*_*ski 0

您可以将整个数据帧转换为 numpy 数组,然后再仅使用array = np.array(df). 它肯定会提高性能。您还可以使用多线程模块来并行处理并提高性能。您还可以使用 pandas .apply()而不是使用.iterrows()