在Python中基于交集合并两个表

在Python中基于交集合并两个表,python,pandas,Python,Pandas,假设我有两张桌子A和B,其中 A是 B是 我必须以这样一种方式合并它们,使新表看起来像这样 对于A和B中的公共第一个元素,我取具有公共第一个元素的两行中间元素的加权平均值。例如: A和B有共同的'AAA',所以我将使用(5*3+5*2)/(3+2)=5计算中间元素。因此,第三个表的第一行变为“AAA”,5,3+2=5 我知道如果我使用列表,可以通过迭代所有元素来实现,但是有没有更快的方法来实现呢 edit来自评论:我还在寻找一种更简单的使用熊猫的方法。DataFrame最简单的纯pytho

假设我有两张桌子A和B,其中

A是

B是

我必须以这样一种方式合并它们,使新表看起来像这样

对于A和B中的公共第一个元素,我取具有公共第一个元素的两行中间元素的加权平均值。例如:

A和B有共同的'AAA',所以我将使用(5*3+5*2)/(3+2)=5计算中间元素。因此,第三个表的第一行变为“AAA”,5,3+2=5

我知道如果我使用列表,可以通过迭代所有元素来实现,但是有没有更快的方法来实现呢


edit来自评论:我还在寻找一种更简单的使用熊猫的方法。DataFrame

最简单的纯python解决方案是使用类似字典的数据结构,键是标签,值对(值=数量*重量,数量):

更简单的是,它使用了
pandas

import pandas as pd

# first let's create dataframes
colnames = 'label weight quantity'.split()
A = pd.DataFrame.from_records([
        ('A', 5, 3),
        ('B', 6, 1),
        ('D', 10, 2),
        ('C', 2, 4),
    ], columns=colnames)

B = pd.DataFrame.from_records([
        ('A', 5, 2),
        ('D', 2, 1),
        ('B', 5, 4),
    ], columns=colnames)

# we can just concatenate those DataFrames and do calculation:
df = pd.concat([A, B])
df['value'] = df.weight * df.quantity

# sum each group with the same label
df = df.groupby('label').sum()
del df['weight']  # it got messed up anyway and we don't need it

# and calculate means:
df['mean'] = df.value / df.quantity

print df
print(df[['mean', 'quantity']])
#            mean  quantity
# label
# A      5.000000         5
# B      5.200000         5
# C      2.000000         4
# D      7.333333         3

最简单的纯python解决方案是使用类似字典的数据结构,键是标签,值对(value=quantity*weight,quantity):

更简单的是,它使用了
pandas

import pandas as pd

# first let's create dataframes
colnames = 'label weight quantity'.split()
A = pd.DataFrame.from_records([
        ('A', 5, 3),
        ('B', 6, 1),
        ('D', 10, 2),
        ('C', 2, 4),
    ], columns=colnames)

B = pd.DataFrame.from_records([
        ('A', 5, 2),
        ('D', 2, 1),
        ('B', 5, 4),
    ], columns=colnames)

# we can just concatenate those DataFrames and do calculation:
df = pd.concat([A, B])
df['value'] = df.weight * df.quantity

# sum each group with the same label
df = df.groupby('label').sum()
del df['weight']  # it got messed up anyway and we don't need it

# and calculate means:
df['mean'] = df.value / df.quantity

print df
print(df[['mean', 'quantity']])
#            mean  quantity
# label
# A      5.000000         5
# B      5.200000         5
# C      2.000000         4
# D      7.333333         3

您可以做得更好,但这里有一个
pandas
解决方案

In [1]: import pandas as pd
In [2]: import numpy as np
In [3]: df1 = pd.DataFrame({'AAA':np.array([5,3]),'BBB':np.array([6,1]),
 .....: 'DDD':np.array([10,2]),'CCC':np.array([2,4])})
In [4]: df2 = pd.DataFrame({'AAA':np.array([5,2]),'DDD':np.array([2,1]),
 .....: 'BBB':np.array([5,4])})
In [5]: df = pd.concat([df1,df2])
In [6]: df.transpose()
      0  1   0   1
AAA   5  3   5   2
BBB   6  1   5   4 
CCC   2  4 NaN NaN
DDD  10  2   2   1
In [7]: vals = np.nan_to_num(df.values)
In [8]: _mean = (vals[0,:]*vals[1,:]+vals[2,:]*vals[3,:])/(vals[1,:]+vals[3,:])
In [9]: _sum = (vals[1,:]+vals[3,:])
In [10]: result = pd.DataFrame(columns = df.columns,data = [_mean,_sum], index=['mean','sum'])
In [11]: result.transpose()
         mean  sum
AAA  5.000000    5
BBB  5.200000    5
CCC  2.000000    4
DDD  7.333333    3

这可能不是最优雅的解决方案,但可以完成任务。

您可以做得更好,但这里有一个
解决方案

In [1]: import pandas as pd
In [2]: import numpy as np
In [3]: df1 = pd.DataFrame({'AAA':np.array([5,3]),'BBB':np.array([6,1]),
 .....: 'DDD':np.array([10,2]),'CCC':np.array([2,4])})
In [4]: df2 = pd.DataFrame({'AAA':np.array([5,2]),'DDD':np.array([2,1]),
 .....: 'BBB':np.array([5,4])})
In [5]: df = pd.concat([df1,df2])
In [6]: df.transpose()
      0  1   0   1
AAA   5  3   5   2
BBB   6  1   5   4 
CCC   2  4 NaN NaN
DDD  10  2   2   1
In [7]: vals = np.nan_to_num(df.values)
In [8]: _mean = (vals[0,:]*vals[1,:]+vals[2,:]*vals[3,:])/(vals[1,:]+vals[3,:])
In [9]: _sum = (vals[1,:]+vals[3,:])
In [10]: result = pd.DataFrame(columns = df.columns,data = [_mean,_sum], index=['mean','sum'])
In [11]: result.transpose()
         mean  sum
AAA  5.000000    5
BBB  5.200000    5
CCC  2.000000    4
DDD  7.333333    3

它可能不是最优雅的解决方案,但可以完成任务。

请向我们展示您尝试了什么,并写出问题所在。您使用的是什么数据结构?那是熊猫。数据框吗?@Akavall很抱歉没有具体说明,我正在帮助一位朋友。我询问了正在使用的数据结构,它实际上是一个
DataFrame
。数据是从两个文件加载的,在合并后,如我上面所示,它被转储到一个文件中。我没有任何数据帧的经验,因此我将开始阅读有关它的内容,同时,如果您知道如何执行此任务,请帮助我。请付出一些努力,我们可以帮助您平滑粗糙的边缘;你说你知道如何使用列表-为什么不给我们看看这个?(请同时查看)请告诉我们您尝试了什么,并写下了什么问题您使用的是什么数据结构?那是熊猫。数据框吗?@Akavall很抱歉没有具体说明,我正在帮助一位朋友。我询问了正在使用的数据结构,它实际上是一个
DataFrame
。数据是从两个文件加载的,在合并后,如我上面所示,它被转储到一个文件中。我没有任何数据帧的经验,因此我将开始阅读有关它的内容,同时,如果您知道如何执行此任务,请帮助我。请付出一些努力,我们可以帮助您平滑粗糙的边缘;你说你知道如何使用列表-为什么不给我们看看这个?(请参见)谢谢,我也在寻找一种使用熊猫的更简单方法。如果我发现了什么,DataFrame将发布。如果它解决了您的问题,您可以+1并接受答案谢谢详细的熊猫回答!谢谢,我也在使用熊猫搜索一种更简单的方法。如果我发现了什么,DataFrame将发布。如果它解决了您的问题,您可以+1并接受答案谢谢详细的熊猫回答!