【问题标题】:vectorized way to compare each element in numpy array比较numpy数组中每个元素的矢量化方法
【发布时间】:2021-03-07 16:00:06
【问题描述】:

我想知道是否有一种方法可以比较 numpy 数组中的每个元素(无论索引位置如何)。 我经常发现自己使用来自 pandas 数据帧的数组,并且我想使用底层的 numpy 数组来比较每个元素。我知道我可以像这样进行快速元素比较:

dfarr1 = pd.DataFrame(np.arange(0,1000))
dfarr2 = pd.DataFrame(np.arange(1000,0,-1))
dfarr1.loc[(dfarr1.values == dfarr2.values)]
# outputs: 500

(显然,上面只是一个玩具示例) 但我想做的是相当于对所有元素进行两个循环,但以尽可能快的方式:

for ir in df.itertuples():
   for ir2 in country_df.itertuples():
      if df['city'][ir[0]] == country_df['Capital'][ir2[0]]:
         df['country'][ir[0]] = country_df['Country'][ir2[0]]

问题是我的数据帧包含数千个元素,而上面的元素太慢了(尤其是考虑到我确信将来我会在不同的、同样长的数据帧上执行类似的此类操作,因此清除此一劳永逸会很好)。 这个想法是我已经解析了几千个文件并获得了它们的地理数据(上面的=df),并且我有一个相当大的文件,其中包含城市及其对应的国家/地区作为查找(=country_df)。这个想法是查看 df 中的城市是否与查找中的城市匹配,如果是,我想在 df 的新列(在同一行索引处)中添加相应的国家和解析的地理数据。无论如何,这只是我需要(理想情况下)比上述方式更高的速度的一个例子。 非常感谢!

【问题讨论】:

  • 如果我理解正确,您希望将每个元素与其他元素进行比较,在这种情况下,我认为np.equal.outer 可能会有所帮助。如果您需要为字符串执行此操作,请查看this 帖子
  • 你说你想“比较每个元素而不考虑索引位置”,然后在下一句中你说你想进行元素比较。是哪个?
  • 是的,对不起,我的意思是所有元素,而不考虑索引位置,即等于两个天真的循环(如第二个示例所示)。如果可以使用 np.equal.outer 那就太好了。我不太明白链接中的解决方案如何为我工作,但我会在明天左右尝试更多。

标签: python arrays pandas numpy


【解决方案1】:

你可以试试这个:

 df1 = pd.DataFrame({'city': ['New York City', 'Los Angeles', 'Paris', 'Berlin', 'Beijing'], 
                     'country' : [None, None, None, None, None] })

df2 = pd.DataFrame({'city' : ['New York City', 'Paris', 'Berlin', 'Beijing', 'Los Angeles', 'Rome'],
                    'country': ['USA', 'France', 'Germany', 'China', 'USA', 'Italy']})

现在我们在df1 上使用fillna 方法,以df2['country'] 系列作为填充值:

df1['country'] = df1.set_index('city')['country'].fillna(df2.set_index('city')['country'])\
                    .reset_index(drop=True)

print(df1)

    city          country
0   New York City  USA
1   Los Angeles    USA
2   Paris          France
3   Berlin         Germany
4   Beijing        China

【讨论】:

  • 非常感谢!很有用。尽管我仍然需要弄清楚如何使用此解决方案来获取 df1 和 df2 中的城市之间存在匹配的实例的索引,然后使用该索引将相应的国家/地区(在 df2 的另一列中)添加到一列在df2中。因此,假设行中的城市,df1 中的列索引 i,k 匹配行中的城市,df2 中的列索引 j,l 然后我想将 j,l+1 处的 df2 中的相应国家添加到 i,k 处的 df1 +1。最好使用上述解决方案作为布尔数组将国家/地区从 df2 复制到 df1,但 df1 和 df2 的长度不等。
  • 不客气!如果您可以为 df1 和 df2 创建一个小样本数据框,那么我们可以在我们的系统中重现 df1、df2,并准确显示您想要的输出。通过这样做,我保证您会在不到一个小时内从我或其他出色的 Stackoverflow 社区成员那里得到答案。
  • 好的,非常感谢!我在这里将 dfs 表示为字典: df1 = {'city': ['New York City', 'Los Angeles', 'Paris', 'Berlin', 'Beijing'], 'Country' : [None, None , None, None, None] } and df2 = {'city' : ['New York City', 'Paris', 'Berlin', 'Beijing', 'Los Angeles', 'Rome'], 'country': [ “美国”、“法国”、“德国”、“中国”、“美国”、“意大利”}。目标是从这样的匹配: df1['city'][2] == df2['city'][1] (= 'Paris') 进入 df2['country'[[1 ] 尽快进入 df1['country'][2] (=France)。 df1 和 df2 的长度不等。
  • 我刚刚使用您提供的新数据编辑了我的答案。让我知道它是否有效。
  • 好的,我想我现在已经接受了你的回答,但我似乎还没有任何投票权:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-25
  • 2021-09-19
  • 2017-01-19
相关资源
最近更新 更多