【问题标题】:Concat strings from dataframe columns in a loop (Python 3.8)在循环中连接来自数据框列的字符串(Python 3.8)
【发布时间】:2021-07-15 11:15:34
【问题描述】:

假设我有一个包含字符串和数字的 DataFrame "DS_df"。 “LAultimateparentcountry”、“borrowerultimateparentcountry”和“tot”三列构成关系。

如何从这三列中创建一个字典(对于整个数据集,而顺序很重要)?我需要将这两个国家作为一个变量访问,而 tot 作为另一个变量。到目前为止,我已经尝试过下面的代码,但这只会给我一个包含单独项目的列表。出于某种原因,我也无法让 .join 工作,因为 df 非常大(+900k 行)。

new_list =[]

for i, row in DS_df.iterrows():
    new_list.append(row["LAultimateparentcountry"])
    new_list.append(row["borrowerultimateparentcountry"])
    new_list.append(row["tot"])

首选的结果是字典,例如,我可以在其中访问“Ge​​rmany_Switzerland”:56708。非常感谢任何帮助或建议。

干杯

【问题讨论】:

    标签: python pandas string loops concatenation


    【解决方案1】:

    你可以这样使用字典:

    countries_map = {}
    
    for index, row in DS_df.iterrows():
        curr_rel = f'{row["LAultimateparentcountry"]}_{row["borrowerultimateparentcountry"]}'
        countries_map[curr_rel] = row["tot"]
    

    如果您不想超过现有的键值

    (并使用他们的首次亮相):

    countries_map = {}
    for index, row in DS_df.iterrows():
        curr_rel = f'{row["LAultimateparentcountry"]}_{row["borrowerultimateparentcountry"]}'
        if curr_rel not in countries_map.keys():
            countries_map[curr_rel] = row["tot"]
    

    【讨论】:

    • 最后一个对我有用,非常感谢。有没有机会我现在可以从重复项中删除它?
    • @MaximilianBach 在键中没有重复。如果您在 df 中有更多匹配项,它将在 dict 中具有匹配值的 curr 键上运行。如果您的意思是值,如果字典中已经存在一个值,您是否希望忽略它?
    • 是的。抱歉不精确,我对这个领域相当陌生。这确实是我所指的价值!是否可以首先将其删除/忽略?感谢您的帮助。
    • @MaximilianBach 如果 dict 值中不存在 cond,您可以添加它。重新编辑主要答案。
    • 谢谢。如果我只忽略那些,国家关系在哪里重复?据我所见,我也忽略了“tot”列中的重复项。因此,即 Albania_UAE = 1 和 Albania_Spain = 1 都被忽略且未添加,因为 Albania_Argentina = 1 已经存在值 1。我将如何保持这些国家/地区的独特关系,而仍然允许值中的重复?再次感谢您的耐心等待!
    【解决方案2】:

    在数据帧上执行操作时,最好按列而不是按行来考虑解决方案。

    如果您的数据帧有 900k+ 行,那么在数据帧上应用矢量化操作可能是一个不错的选择。

    以下是两种解决方案:

    使用 pd.Series + to_dict():

    pd.Series(DS_df.tot.values, index=DS_df.LAultimateparentcountry.str.cat(DS_df.borrowerultimateparentcountry, sep="_")).to_dict()
    

    使用 zip() + dict():

    dict(zip(DS_df.LAultimateparentcountry.str.cat(DS_df.borrowerultimateparentcountry, sep="_"), DS_df.tot))
    

    测试数据框:

        DS_df = DataFrame({
            'LAultimateparentcountry':['India', 'Germany', 'India'],
            'borrowerultimateparentcountry':['France', 'Ireland', 'France'],
            'tot':[56708, 87902, 91211]
        })
    DS_df
    
    
    LAultimateparentcountry borrowerultimateparentcountry   tot
    0   India   France  56708
    1   Germany Ireland 87902
    2   India   France  91211
    

    两种解决方案的输出:

    {'India_France': 91211, 'Germany_Ireland': 87902}
    

    如果形成的键有重复,则值将被更新。

    哪种解决方案性能更高?

    简短回答 -
    zip() + dict() # 如果行是大约。 1000000以下
    pd.Series + to_dict() # 如果行是大约。 100万以上

    长答案 - 以下是测试:

    测试 30 行 3 列

    zip() + 字典()

    %timeit dict(zip(DS_df.LAultimateparentcountry.str.cat(DS_df.borrowerultimateparentcountry, sep="_"), DS_df.tot))
    
    297 µs ± 21 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    

    pd.Series + to_dict():

    %timeit pd.Series(DS_df.tot.values, index=DS_df.LAultimateparentcountry.str.cat(DS_df.borrowerultimateparentcountry, sep="_")).to_dict()
    
    506 µs ± 35.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    

    测试 6291456 行 3 列

    pd.Series + to_dict()

    %timeit pd.Series(DS_df.tot.values, index=DS_df.LAultimateparentcountry.str.cat(DS_df.borrowerultimateparentcountry, sep="_")).to_dict()
    3.92 s ± 77.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    

    zip + dict()

    %timeit dict(zip(DS_df.LAultimateparentcountry.str.cat(DS_df.borrowerultimateparentcountry, sep="_"), DS_df.tot))
    3.97 s ± 226 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-30
      • 2016-12-15
      • 2015-12-16
      • 2013-07-07
      相关资源
      最近更新 更多