【问题标题】:How to make nested for loops work faster?如何使嵌套的 for 循环工作得更快?
【发布时间】:2022-01-26 00:34:33
【问题描述】:

我有一个 DF,其 A 列包含位置名称(即城市 Xxx、Yyy 村、Zzz 镇),另一个 DF1 的 B 列包含已清理的位置名称(不包括城市、村庄等),C 列具有相应的状态名字。我想将 DF 列 A 中的值与 DF1 列 B 匹配,如果在列中将 col B 和 Col C 复制到 DF example

我有下一个可以运行但速度太慢的代码:

for index in range(len(DF)):
    for name in range(len(DF1)):
        if data1.loc[name, 'B'] in data.loc[index, 'A']:
            data.loc[index, 'B'] = data1.loc[name, 'B']
            data.loc[index, 'C'] = data1.loc[name, 'C'] 

有什么方法可以加快速度吗?

【问题讨论】:

  • 这似乎是.isin 的工作,但我仍在考虑如何应用它。
  • 请为您提供输入/输出数据集作为数据框构造函数,而不是图像。图像不可重复且不明确。

标签: python pandas dataframe filter


【解决方案1】:

这里有一个比我之前发布的更好的解决方案。它还应该需要更少的内存。

df[['B','C']] = df1['B'].apply(lambda x: df1[['B','C']].loc[df['A'].str.contains(x)].iloc[0])

注意:如果 DF1 只有两列,您可以删除 lambda 函数中的 [['B', 'C']],因为它不是必需的。

此外,如果您只需要位置名称而不需要其前面的单词(城镇、城市等),您可以使用 B 的值更新 A,而无需创建另一个不必要的列:

df[['A','C']] = df1['B'].apply(lambda x: df1[['B','C']].loc[df['A'].str.contains(x)].iloc[0])

【讨论】:

  • 得到这个“MemoryError: Unable to allocate 1.55 GiB for an array with shape (3, 69343274) and data type float64”。两个 DF 都是相当大的 24k 和 3k 行,22 和 15 列
  • @AntonBagaev 您在 DF["A"] 中的值是否总是在实际位置名称之前只包含一个单词(例如城镇、城市、村庄等)?如果没有,你真的需要那部分吗?
  • 不,并不总是可以是一个、两个和三个单词,后跟一个或两个地名单词。我只需要一个地名
  • @AntonBagaev 我编辑了我的答案并包含了一个更好的解决方案。让我知道它是否有效(:
  • 收到错误“IndexError: single positional indexer is out-of-bounds”
【解决方案2】:

您可以将 DF 拆分为多个部分,并为每个部分使用多处理或多线程来同时运行这些进程。这个link 可能有用。

【讨论】:

    猜你喜欢
    • 2014-08-20
    • 2020-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多