使用多个键将pandas数据框转换为字典

时间:2018-09-05 19:27:51

标签: pandas loops dictionary key jupyter

我正在尝试使用四个键将数据帧转换为字典,这些键全部来自列。我也有多个列,我想通过使用由这四个列构建的键来返回值。我用循环的方式工作,但最终遇到内存错误。我很好奇,有没有更有效的方法呢?

数据框如下:

    Service Bill Weight Zone    Resi    UPS FedEx   USPS    DHL
    1DEA           1       2    N      33.02    9999    9999    9999
    1DEA           2       2    N      33.02    9999    9999    9999
    1DEA           3       2    N      33.02    9999    9999    9999

我想为每个运营商提供一个密钥,如下所示:

    price[('1DEA', '1', '2', 'N', 'UPS')]=33.02
    price[('1DEA', '1', '2', 'N', 'FedEx')]=9999

我已经尝试过了:

    price = {}
    carriers = ['UPS', 'FedEx', 'USPS','DHL'] 
    for carrier in carriers:
        for row in rate_keys.to_dict('records'):
              key = (row['Service'], row['Bill Weight'], row['Zone'], 
              row['Resi'], carrier)
              rate_keys[key] = row[carrier]

5 个答案:

答案 0 :(得分:4)

将索引设置为除载体列以外的所有索引,然后堆栈。

df.set_index(['Service', 'Bill Weight', 'Zone', 'Resi']).stack().to_dict()

{('1DEA', 1, 2, 'N', 'DHL'): 9999.0,
 ('1DEA', 1, 2, 'N', 'FedEx'): 9999.0,
 ('1DEA', 1, 2, 'N', 'UPS'): 33.02,
 ('1DEA', 1, 2, 'N', 'USPS'): 9999.0,
 ('1DEA', 2, 2, 'N', 'DHL'): 9999.0,
 ('1DEA', 2, 2, 'N', 'FedEx'): 9999.0,
 ('1DEA', 2, 2, 'N', 'UPS'): 33.02,
 ('1DEA', 2, 2, 'N', 'USPS'): 9999.0,
 ('1DEA', 3, 2, 'N', 'DHL'): 9999.0,
 ('1DEA', 3, 2, 'N', 'FedEx'): 9999.0,
 ('1DEA', 3, 2, 'N', 'UPS'): 33.02,
 ('1DEA', 3, 2, 'N', 'USPS'): 9999.0}

理解力

{(*r[:4], c): v for r in df.values for c, v in zip(df.columns[4:], r[4:])}

{('1DEA', 1, 2, 'N', 'DHL'): 9999,
 ('1DEA', 1, 2, 'N', 'FedEx'): 9999,
 ('1DEA', 1, 2, 'N', 'UPS'): 33.02,
 ('1DEA', 1, 2, 'N', 'USPS'): 9999,
 ('1DEA', 2, 2, 'N', 'DHL'): 9999,
 ('1DEA', 2, 2, 'N', 'FedEx'): 9999,
 ('1DEA', 2, 2, 'N', 'UPS'): 33.02,
 ('1DEA', 2, 2, 'N', 'USPS'): 9999,
 ('1DEA', 3, 2, 'N', 'DHL'): 9999,
 ('1DEA', 3, 2, 'N', 'FedEx'): 9999,
 ('1DEA', 3, 2, 'N', 'UPS'): 33.02,
 ('1DEA', 3, 2, 'N', 'USPS'): 9999}

答案 1 :(得分:2)

IIUC,具有这样的列表理解:

carriers = ['UPS', 'FedEx', 'USPS','DHL']
price = {(row['Service'], row['Bill Weight'], row['Zone'], row['Resi'], c):row[c]
     for c in carriers for _, row in df.iterrows()}

[输出]

{('1DEA', 1, 2, 'N', 'UPS'): 33.02,
 ('1DEA', 2, 2, 'N', 'UPS'): 33.02,
 ('1DEA', 3, 2, 'N', 'UPS'): 33.02,
 ('1DEA', 1, 2, 'N', 'FedEx'): 9999,
 ('1DEA', 2, 2, 'N', 'FedEx'): 9999,
 ('1DEA', 3, 2, 'N', 'FedEx'): 9999,
 ('1DEA', 1, 2, 'N', 'USPS'): 9999,
 ('1DEA', 2, 2, 'N', 'USPS'): 9999,
 ('1DEA', 3, 2, 'N', 'USPS'): 9999,
 ('1DEA', 1, 2, 'N', 'DHL'): 9999,
 ('1DEA', 2, 2, 'N', 'DHL'): 9999,
 ('1DEA', 3, 2, 'N', 'DHL'): 9999}

答案 2 :(得分:2)

循环播放时,您可能不应该更新rate_keys。我想您的示例脚本的最后一行应显示为

price[key] = row[carrier]

答案 3 :(得分:0)

如果愿意

df = df.set_index(['Service', 'Bill','Weight','Zone'])

您本质上是同一件事

输出

print(df.loc[('1DEA', 1, 2, 'N')]['UPS'])

9999.0

答案 4 :(得分:0)

首先,

temp = df.set_index(['Service', 'Bill', 'Weight', 'Zone']).to_dict()

然后,我们进行字典理解以获得所需的输出,

dict(((k+(i,)), a[i][k]) for i in temp for (k) in temp[i] )