首页 > 解决方案 > 组合 pandas 将结果作为单个数据框中的多列应用

问题描述

概括

假设您applyfunction一个 groupby 对象,因此其中g.apply的每一个都gdf.groupby(...)您提供了一个系列/数据框。如何将这些结果组合到一个数据框中,但将组名作为列?

细节

我有一个event_df看起来像这样的数据框:

index   event   note   time
0       on      C      0.5
1       on      D      0.75
2       off     C      1.0
...

我想event为每个创建一个采样note,并且采样有时由以下给出t_df

index    t
0        0
1        0.5
2        1.0
...

所以我会得到这样的东西。

t        C         D        
0        off       off
0.5      on        off
1.0      off       on
...

到目前为止我所做的:

def get_t_note_series(notedata_row, t_arr):
   """Return the time index in the sampling that corresponds to the event."""
   t_idx = np.argwhere(t_arr >= notedata_row['time']).flatten()[0]
   return t_idx

def get_t_for_gb(group, **kwargs):
   t_idxs = group.apply(get_t_note_series, args=(t_arr,), axis=1)
   t_idxs.rename('t_arr_idx', inplace=True)
   group_with_t = pd.concat([group, t_idxs], axis=1).set_index('t_arr_idx')
   print(group_with_t)
   return group_with_t


t_arr = np.arange(0,10,0.5)
t_df = pd.DataFrame({'t': t_arr}).rename_axis('t_arr_idx')
gb = event_df.groupby('note')
gb.apply(get_t_for_gb, **kwargs)

所以我得到的是每个音符的许多数据帧,大小相同(与 t_df 相同):

t     event
0     on
0.5   off
...

t     event
0     off
0.5   on
...

如何从这里转到我想要的数据框,每个组对应于新数据框中的一列,索引是t

标签: pythonpandas

解决方案


编辑:对不起,我没有考虑到下面,你重新调整你的time列并且现在不能提供一个完整的解决方案,因为我必须离开,但我认为,你可以通过使用pandas.merge_asof你的两个数据框来进行重新调整以获得最近的“重新调整”时间并从合并的数据框中您可以尝试下面的代码。我希望这是你想要的。

import pandas as pd
import io 

sio= io.StringIO("""index   event   note   time
0       on      C      0.5
1       on      D      0.75
2       off     C      1.0""")
df= pd.read_csv(sio, sep='\s+', index_col=0)

df.groupby(['time', 'note']).agg({'event': 'first'}).unstack(-1).fillna('off')

取每个 time-note group by 中的第一行agg({'event': 'first'}),然后使用note-index 列并将其转置,因此note值变为列。然后在最后填充所有单元格,通过 'off' 找不到任何数据点fillna

这输出:

Out[28]: 
     event     
note     C    D
time           
0.50    on  off
0.75   off   on
1.00   off  off

您可能还想尝试min,或者max以防开/关对于时间/音符的组合不是明确的(如果同一时间/音符有更多行,其中一些开而一些关)并且您更喜欢其中一个值(比如说如果有一个开,那么无论有多少关,你都想要一个开等)。如果您想要市长投票之类的东西,我建议在聚合数据框中(在 之前unstack())添加市长投票列。


推荐阅读