3

以下链接使用python字典解决了一个非常相似的问题Python:将字典与列表中的列表合并为值并计算它们

我想知道是否可以使用 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 库进行此类操作是否有效

4

1 回答 1

3

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
于 2012-12-24T11:26:09.847 回答