concat + groupby + 应用于熊猫数据框中的多列
concat + groupby + apply in multiple columns in panda dataframe
我有以下两个数据框:
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'])
这可能吗?
来自 df1
和 df2
的列:
- 创建一个
list
的列名
used_cols = ['return', 'high_low', 'turnover']
数据帧列表:
- 使用列表推导式创建 DataFrame 列表
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_list
与 concat
merged = pd.concat(df_list, axis=1).reset_index()
最终数据帧:
比较使用新代码和原始代码创建的数据帧:
merged_new == merged_old
最终代码:
- 与 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()
考虑一个简单的 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
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'])
这可能吗?
来自 df1
和 df2
的列:
- 创建一个
list
的列名
used_cols = ['return', 'high_low', 'turnover']
数据帧列表:
- 使用列表推导式创建 DataFrame 列表
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_list
与concat
merged = pd.concat(df_list, axis=1).reset_index()
最终数据帧:
比较使用新代码和原始代码创建的数据帧:
merged_new == merged_old
最终代码:
- 与 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()
考虑一个简单的 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