concat+groupby+在panda datafram的多个列中应用

2024-05-20 19:36:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下两个数据帧:

df1型

ticker       date       return      high_low      turnover
CRM         2017-01-03  0.018040    0.026957    5.722346e+08
MSFT        2017-01-03  -0.003344   0.011428    1.295037e+09
CRM         2017-01-04  0.024198    0.032646    6.762756e+08
MSFT        2017-01-04  -0.002881   0.010142    1.329482e+09
CRM         2017-01-05  -0.000275   0.015580    3.417927e+08

df2型:

ticker       date       return      high_low    turnover
CRM         2017-01-03  0.018040    0.026957    5.722318e+08
MSFT        2017-01-03  -0.003344   0.011509    1.295037e+09
CRM         2017-01-04  0.024198    0.032575    6.761264e+08
MSFT        2017-01-04  -0.002881   0.010142    1.329480e+09
CRM         2017-01-05  -0.000275   0.015580    3.417930e+08

我有下面的代码。 但我想把最后四行简化成一行是可能的。在一行中执行三列的concat+groupby+apply。你知道吗

def get_min_absvalue(values):
    return min(values, key = abs)

#simplify the following 4 lines in 1?
consolidated_return=(pd.concat((df1,df2),ignore_index=True,sort=False).groupby(['date','ticker'])['return'].apply(lambda x: get_min_absvalue(x)).reset_index())
consolidated_high_low=(pd.concat((df1,df2),ignore_index=True,sort=False).groupby(['date','ticker'])['high_low'].apply(lambda x: get_min_absvalue(x)).reset_index())
consolidated_turnover=(pd.concat((df1,df2),ignore_index=True,sort=False).groupby(['date','ticker'])['turnover'].apply(lambda x: get_min_absvalue(x)).reset_index())

merged = consolidated_return.merge(consolidated_high_low, on=['date', 'ticker']).merge(consolidated_turnover, on=['date', 'ticker'])

有可能吗?你知道吗


Tags: dateindexreturnminlowtickercrmdf1
2条回答

考虑一个简单的min聚合调用:

agg_df = (pd.concat([df1,df2], ignore_index=True, sort=False)
              .groupby(['date','ticker'], as_index=False)
              .min()
         )

print(agg_df)
#         date ticker    return  high_low      turnover
# 0 2017-01-03    CRM  0.018040  0.026957  5.722318e+08
# 1 2017-01-03   MSFT -0.003344  0.011428  1.295037e+09
# 2 2017-01-04    CRM  0.024198  0.032575  6.761264e+08
# 3 2017-01-04   MSFT -0.002881  0.010142  1.329480e+09
# 4 2017-01-05    CRM -0.000275  0.015580  3.417927e+08

print(merged.eq(agg_df))
#    date  ticker  return  high_low  turnover
# 0  True    True    True      True      True
# 1  True    True    True      True      True
# 2  True    True    True      True      True
# 3  True    True    True      True      True
# 4  True    True    True      True      True

对于真绝对值最小聚合:

agg_df = (pd.concat([df1,df2], ignore_index=True, sort=False)
              .groupby(['date','ticker'], as_index=False)['return', 'high_low', 'turnover']
              .apply(lambda x: x.abs().min())
              .reset_index()
            )

print(agg_df)

#         date ticker    return  high_low      turnover
# 0 2017-01-03    CRM  0.018040  0.026957  5.722318e+08
# 1 2017-01-03   MSFT  0.003344  0.011428  1.295037e+09
# 2 2017-01-04    CRM  0.024198  0.032575  6.761264e+08
# 3 2017-01-04   MSFT  0.002881  0.010142  1.329480e+09
# 4 2017-01-05    CRM  0.000275  0.015580  3.417927e+08

来自df1&;df2的列:

  • 创建列名的list
used_cols = ['return', 'high_low', 'turnover']

数据帧列表:

  • 使用列表理解创建数据帧列表
df_list = [pd.concat((df1, df2), ignore_index=True, sort=False).groupby(['date', 'ticker'])[v].apply(lambda x: min(x, key=abs)) for v in used_cols]

df_list的内容:

  • 它们属于pandas.core.series.Series类型
df_list[0]

date        ticker
2017-01-03  CRM       0.026957
            MSFT      0.011428
2017-01-04  CRM       0.032575
            MSFT      0.010142
2017-01-05  CRM       0.015580
Name: high_low, dtype: float64

使用concat而不是merge

  • 很容易将df_listconcat结合起来
merged = pd.concat(df_list, axis=1).reset_index()

最终数据帧:

enter image description here

比较使用新代码和原始代码创建的数据帧:

merged_new == merged_old

enter image description here

最终代码:

  • 与6行代码相比,只有3行代码,并且没有重复。你知道吗
used_cols = ['return', 'high_low', 'turnover']
df_list = [pd.concat((df1, df2), ignore_index=True, sort=False).groupby(['date', 'ticker'])[v].apply(lambda x: min(x, key=abs)) for v in used_cols]
merged = pd.concat(df_list, axis=1).reset_index()

相关问题 更多 >