根据每个行值以两个其他数据帧创建新数据帧

时间:2018-04-01 22:55:19

标签: python pandas dataframe

我有2个数据框

Name1    Value
A1         1
A2         2
A3         0
A4        -3

Name2    Value
B1         1
B2        -1
B3       -10
B4         4

现在我需要第三个数据框,它根据条件选择上面两个数据帧的行,特别是:“选择具有较小值的行”

Desired Output
A1         1         # <- What happens when tied?
B2        -1
B3       -10
A4        -3

接下来的问题是如果有关系会发生什么?实际上,我会公开采取第一个,或随机选择,无论更容易。

4 个答案:

答案 0 :(得分:3)

我们可以通过将df1和df2值压缩在一起并使用min()传递密钥来重新创建数据框:

df3 = pd.DataFrame((min(i, key = lambda x: x[1]) for i in zip(df1.values, df2.values)),
                   columns = ['Desired','Output'])

返回:

  Desired  Output
0      A1       1
1      B2      -1
2      B3     -10
3      A4      -3

答案 1 :(得分:2)

这是一种方式,假设您从数据框df1df2开始。

res = df1.rename(columns={'Name1': 'Name'})\
         .append(df2.rename(columns={'Name2': 'Name'}))\
         .sort_values('Value')

res = res.loc[~res.index.duplicated()]\
         .sort_index()

<强>结果

  Name  Value
0   A1      1
1   B2     -1
2   B3    -10
3   A4     -3

<强>解释

有两个步骤:

  1. 在对齐列名并按df2排序后,将df1附加到Value
  2. 按索引删除重复项,然后按索引排序。

答案 2 :(得分:2)

一种方法是将第三个数据框创建为其中一个初始数据框的副本,然后替换其他数据框中对应部分较小的值:

df3 = df1.copy()
# Change this expression to choose how to treat ties
min_mask = df1.Value>df2.Value  # i.e. df1.Value>=df2.Value
df3.loc[min_mask] = df2.rename(columns={'Name2':'Name1'})[min_mask]

输出df3

 Name1  Value
0   A1     1
1   B2    -1
2   B3   -10
3   A4    -3

rename中有一个df2,以便将整行写入df3,否则,名称不同的列会获得NaN值。

关于关系,您可以通过更改大于或等于的大小来轻松选择您想要做的事情。

编辑:

到目前为止,这个问题有4个答案,所有答案都完全用不同的方法回答问题,因此,根据最终的应用,这个可能不是最佳答案。

为了简化找到适当答案的过程,我发布了4个答案中每个答案的经过时间的摘要,作为df1df2中行数的函数,通常是选择时的关键因素之一。

Elapsed time comparison between methods

答案 3 :(得分:2)

只需使用drop_duplicates

即可
pd.concat([df1,df2.rename(columns={'Name2':'Name1'})]).sort_values('Value').reset_index().drop_duplicates('index').sort_values('index').set_index('index')
Out[36]: 
      Name1  Value
index             
0        A1      1
1        B2     -1
2        B3    -10
3        A4     -3