合并Pandas数据帧:选择较小的绝对值

2024-07-05 10:46:09 发布

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

我有两个熊猫数据帧:

数据帧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

现在我需要第三个“整合”数据帧:

  • 相同的列名
  • 对于每一行,我必须从DataframeA或DataframeB中选择绝对值较小的“return”数据

有什么建议吗?你知道吗


Tags: 数据datereturn建议tickercrmmsftdataframeb
3条回答

这是用可运行代码编辑的新答案

即使行数不相等,下面的代码也可以工作。它将首先获取两个数据帧上的公共行,然后为所需列找到正确的值

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

return上尝试concat+groupby,并用key=abs返回min

(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

您可以使用concat连接这两个dataframe,然后使用groupbyticker分组,并获得每个组的最小值:

df3=pd.concat([df1,df2]).groupby('ticker').min().reset_index()

相关问题 更多 >