我正在寻找一个自定义分组依据函数,该函数将以以下方式对行进行分组:
使事情更清晰的示例:
start_df = pd.DataFrame({"id": [1,1,2,2,3,3,4,4,4,5],
"foo": [4, 4, np.nan, 7, np.nan, np.nan, 0, 9, 9, 7],
"bar": [np.nan, np.nan, 0, 4, 0, 1, 6, 6, 0, 4]})
id foo bar
0 1 4.0 NaN
1 1 4.0 NaN
2 2 NaN 0.0
3 2 7.0 4.0
4 3 NaN 0.0
5 3 NaN 1.0
6 4 0.0 6.0
7 4 9.0 6.0
8 4 9.0 0.0
9 5 7.0 4.0
自定义分组依据之后,id
:
result_df = pd.DataFrame({"id": [1,2,3,4,5], "foo": [4, 7, np.nan, 9, 7], "bar": [np.nan, 4, 1, 6, 4]})
id foo bar
0 1 4.0 NaN
1 2 7.0 4.0
2 3 NaN 1.0
3 4 9.0 6.0
4 5 7.0 4.0
我知道的一个解决方案是:
start_df.groupby("id").max().reset_index()
但是对于我来说情况太慢了,因为我要处理的数据帧很大。另一方面,我无法用这种解决方案来说明两个元素都是数字的极端情况:
start_df.groupby("id").sum(min_count=1).reset_index()
期待您的帮助!
答案 0 :(得分:2)
也许不是您原本想的那样,但这应该可行
start_df.groupby('id').max()
如果要将“ id”重新添加到列中,请使用reset_index
。
答案 1 :(得分:0)
我相信您正在寻找的解决方案非常理想。
我在下面添加了另一种方法,在groupby中指定as_index=False
可以使用groupby.GroupBy.nth保留原始索引
>>> start_df.groupby('id', as_index=False).nth(1)
id foo bar
1 1 4.0 NaN
3 2 7.0 4.0
5 3 NaN 1.0
7 4 9.0 6.0
OR
>>> start_df.groupby(['id'], sort=False).max().reset_index()
id foo bar
0 1 4.0 NaN
1 2 7.0 4.0
2 3 NaN 1.0
3 4 9.0 6.0
答案 2 :(得分:0)
这是不使用groupby
的另一种方法,但我不能确定它是否更有效。想法是每个id具有相同的行数,以便能够reshape
数据并在轴上使用np.nanmax
。为此,您可以生成缺失值为nan的数据框。
#create the count of each id
s = start_df.id.value_counts()
nb_max = s.max()
#ceate the dataframe with nan
df_nan = pd.DataFrame({col: np.nan if col != 'id'
else [ids for ids, val in zip(s.index,nb_max-s.values)
for _ in range(val)]
for col in start_df.columns })
#get the result
result_df = pd.DataFrame( np.nanmax( pd.concat([start_df, df_nan])[start_df.columns]
.sort_values('id').values
.reshape((-1,start_df.shape[1],nb_max)),
axis=1),
columns = start_df.columns)
注意:您会收到一条警告,指出某些切片只是nan
,但它可以起作用,可能有一种方法可以使此警告静音。