我有两个熊猫DataFrame:
数据框A:
date ticker return
2017-01-03 CRM 0.018040121229614625
2017-01-03 MSFT -0.0033444816053511683
2017-01-04 CRM 0.024198086662915008
2017-01-04 MSFT -0.0028809218950064386
2017-01-05 CRM -0.0002746875429199269
2017-01-05 MSFT 0.0017687731146487362
数据框B:
date ticker return
2017-01-03 CRM 0.018040120991250852
2017-01-03 MSFT -0.003344466975803595
2017-01-04 CRM 0.024198103213211475
2017-01-04 MSFT -0.0028809268004892363
2017-01-05 CRM -0.00027464144673694513
2017-01-05 MSFT 0.0017687829680113065
现在我需要第三个“合并”数据框:
有什么建议吗?
答案 0 :(得分:2)
这是具有可运行代码的经过编辑的新答案
即使行数不相等,以下代码也将起作用。它将首先在两个数据帧上使用共同的行,然后为所需的列找到正确的值
import numpy as np
import pandas as pd
## creating dummy data to get runable code
## ---------------------------------------
n_rows = 20
sub_categories = np.random.choice(4, size=n_rows)
dic1 = {
"a": list(range(n_rows)),
"b": sub_categories,
"c": np.random.randn(n_rows)
}
dic2 = {
"a": range(n_rows),
"b": sub_categories,
"c": np.random.randn(n_rows)
}
df1 = pd.DataFrame(dic1)
df1.drop(index=list(np.random.choice(n_rows, 5, replace=False)), inplace=True)
df2 = pd.DataFrame(dic2)
df2.drop(index=list(np.random.choice(n_rows, 3, replace=False)), inplace=True)
## Main Answer
## ---------------------------------------------------------
## merge df1 and df2 then create new column c based which take min(abs(c_1, c_2))
result = df1.merge(df2, how="inner", on=["a","b"], suffixes=["_1", "_2"]).copy()
result["c"] = result["c_1"].where(np.abs(result["c_1"])<np.abs(result["c_2"]),
result["c_2"], axis=0)
display(result)
## finally reindex to remove extra columns
result = result.reindex(columns=["a","b","c"])
result
旧答案
您可以执行以下操作
series = df1["return"].where(np.abs(df1["return"])<np.abs(df2["return"]), df2["return"], axis=0)
series
如果返回的绝对值小于df2中的同一行,则将返回其值从df1中获取的系列,否则它将从df2中获取值
然后您可以替换df1或df2的列或它们的副本以获取所需的数据框
df1["return"] = series
答案 1 :(得分:1)
您可以使用concat
来加入两个dataframe
,然后使用ticker
按groupby
分组并获得每个组的最小值:
df3=pd.concat([df1,df2]).groupby('ticker').min().reset_index()
答案 2 :(得分:0)
在concat+groupby
上尝试return
并返回min
和key=abs
:
(pd.concat((A,B),ignore_index=True)
.groupby(['date','ticker'])['return'].min(key=abs).reset_index())
date ticker return
0 2017-01-03 CRM 0.018040
1 2017-01-03 MSFT -0.003344
2 2017-01-04 CRM 0.024198
3 2017-01-04 MSFT -0.002881
4 2017-01-05 CRM -0.000275
5 2017-01-05 MSFT 0.001769