合并CSV数据和计算python pandas中的单元格值

时间:2012-12-24 10:52:47

标签: python pandas

以下链接使用python词典Python: merging dictionaries with lists in lists as values and counting them

解决了一个非常类似的问题

我想知道使用python pandas库是否可以解决以下问题。我尝试使用合并和连接,但我不知道如何获得所需的结果。

问题如下:

我从2个csv文件中读到字典

dict1 = {'M1': {'H': '1', 'J' : '2'}, 'M2': {'H': '1', 'J' : '2'}, 'M3': {'H': '1', 'J' : '2'}}
dict2 = {'M1': {'H': '4', 'J' : '6'}, 'M2': {'H': '2', 'J' : '5'}, 'M4': {'H': '9', 'J' : '8'}}

必需的输出表:

两个词典中所有键的列表及其两个词典之间匹配键的子词典[{H,J}]总和

示例:M1存在于dict1和dict2中,因此M1的最终输出应为

final_M1 ['H'] = 1(来自dict1 ['M1'])+ 4(来自dict2 ['M1'])= 5

同样对于M3,M3仅出现在dict1中,因此不需要做任何事情并且必须保留这些值。

示例输出:

---------------------
M    |  H  |   J
---------------------
M1   |  5  |   8
---------------------
M2   |  3  |   7
---------------------
M3   |  1  |   2
---------------------
M4   |  9  |   8

获取两个词典的唯一集合,

keys = set(dict1.keys()).union(dict2.keys())

与上面链接中使用的逻辑类似,使用python字典的解决方案如下所示:

for k in keys:
print "Key:", k
d1val = dict1.get(k, {})
d2val = dict2.get(k, {})
if (len(d1val) == 0):
    print "d2val H:", d2val['H']

if (len(d2val) == 0):
    print "d1val H:", d1val['H']

if (len(d1val) != 0 and len(d2val) != 0):
    print "Test"
    print "d1val H:", d1val['H']
    print "d2val H:", d2val['H']
    print "d1val H + d2val H = ", int(d1val['H']) + int(d2val['H'])
print "***********"

如何在python pandas中实现相同的逻辑?如果输入数据集的每个文件的行数为10,000行,我还想使用pandas库进行此类操作是否有效

1 个答案:

答案 0 :(得分:3)

如果嵌套dicts中的值是数字而不是字符串,则可以使用DataFrame.add方法。例如:

import pandas as pd

dict1 = {'M1': {'H': 1, 'J' : 2}, 'M2': {'H': 1, 'J' : 2},
         'M3': {'H': 1, 'J' : 2}}
dict2 = {'M1': {'H': 4, 'J' : 6}, 'M2': {'H': 2, 'J' : 5},
         'M4': {'H': 9, 'J' : 8}}

df1 = pd.DataFrame(dict1).T
df2 = pd.DataFrame(dict2).T

print(df1)

#     H  J
# M1  1  2
# M2  1  2
# M3  1  2

print(df2)
#     H  J
# M1  4  6
# M2  2  5
# M4  9  8

print(df1.add(df2, fill_value = 0))

#     H  J
# M1  5  8
# M2  3  7
# M3  1  2
# M4  9  8

如果您在csv文件中显示数据,也许我们可以建议如何读取它,以便值是数字而不是字符串。

或者,您可以在解析csv之后将字符串转换为数字

In [1]: dict1 = {'M1': {'H': '1', 'J' : '2'}, 'M2': {'H': '1', 'J' : '2'}, 'M3': {'H': '1', 'J' : '2'}}

In [2]: dict1 = {key:{k:int(v) for k,v in dct.items()} for key,dct in dict1.items()}

In [3]: dict1
Out[3]: {'M1': {'H': 1, 'J': 2}, 'M2': {'H': 1, 'J': 2}, 'M3': {'H': 1, 'J': 2}}

但我认为最好从头开始正确解析它,而不是稍后以这种方式修补它。


如果dicts包含数字和字符串值,那么您可以使用连接,然后是groupy和聚合来组合它们。例如,

import pandas as pd
import numpy as np

def combine(values):
    if any(isinstance(v, basestring) for v in values):
        result = values.dropna().tolist()
    else:
        result = values.sum()
    return result

dict1 = { 'M1': {'H': 1, 'J' : 2, 'D' : 'ABC/DEF1.txt'},
          'M2': {'H': 1, 'J' : 2, 'D' : 'ABC/DEF2.txt'},
          'M3': {'H': 1, 'J' : 2, 'D' : 'ABC/DEF3.txt'} }
dict2 = { 'M1': {'H': 4, 'J' : 6, 'D' : 'ABC/DEF1.txt'},
          'M2': {'H': 2, 'J' : 5, 'D' : 'ABC/DEF2.txt'},
          'M4': {'H': 9, 'J' : 8, 'D' : 'ABC/DEF3.txt'}}

df1 = pd.DataFrame(dict1).T
df2 = pd.DataFrame(dict2).T
df = df1.join(df2, rsuffix = '_', how = 'outer').T
grouped = df.groupby(lambda label: label.rstrip('_'))
print(grouped.aggregate(combine).T)

产量

                               D  H  J
M1  [ABC/DEF1.txt, ABC/DEF1.txt]  5  8
M2  [ABC/DEF2.txt, ABC/DEF2.txt]  3  7
M3                [ABC/DEF3.txt]  1  2
M4                [ABC/DEF3.txt]  9  8