【问题标题】:How do you loop and test multiple "numpy.isclose" values on a column of a dataframe?如何在数据框的列上循环和测试多个“numpy.isclose”值?
【发布时间】:2019-03-09 17:51:48
【问题描述】:

我正在使用这行代码来确定大型数据框 df 的列中接近 A 的值(在容差范围内)的值:

df[df[['column']].apply(numpy.isclose, b=A, atol=0.004).any(1)]

但是,在某些情况下,A 可以有多个值(即 2-4 个不同的值)。有没有一种方法可以让我遍历 A 的每个值来测试每个值?我知道上面显示的代码行只允许我使用 A 如果它分配了一个值。

这方面的一个例子是(使用更短的数据框):

   column1   column2
0  0.902062    5.8
1  0.557808    3.3
2  0.655985    3.9
3  0.832471    4.1  
4  0.199884    1.2
5  0.127254    1.8
6  0.771439    4.9
7  0.432289    2.8
8  0.385282    2.2
9  0.783643    3.7

其中 A 有值:

A=[0.432, 0.783, 0.902]

但在另一个示例中,它可能具有以下值:

A=[0.558, 0.002]

(很明显,数据框中的任何内容实际上都不会匹配 0.002)。

我想要一些代码,它能够从数据框中返回 column1 值与所有示例的 A 值匹配的行,无论不同 A 值的数量如何(如果没有匹配,则返回“NaN”)。

【问题讨论】:

标签: python-3.x pandas numpy


【解决方案1】:

我相信在使用 numpy.isclose 之前,您需要通过 numpy.broadcast_to 重复列值:

np.random.seed(142)

df = pd.DataFrame({'column':np.random.rand(10)})
print (df)
     column
0  0.902062
1  0.557808
2  0.655985
3  0.832471
4  0.199884
5  0.127254
6  0.771439
7  0.432289
8  0.385282
9  0.783643

A = [0.432, 0.783, 0.902]

#repeat by length of number of list A
len_A = len(A)
a = np.broadcast_to(df['column'].values[:, None], (len(df),len_A))
print (a)
[[0.90206152 0.90206152 0.90206152]
 [0.55780754 0.55780754 0.55780754]
 [0.65598471 0.65598471 0.65598471]
 [0.83247141 0.83247141 0.83247141]
 [0.19988419 0.19988419 0.19988419]
 [0.12725426 0.12725426 0.12725426]
 [0.77143911 0.77143911 0.77143911]
 [0.43228855 0.43228855 0.43228855]
 [0.38528223 0.38528223 0.38528223]
 [0.78364337 0.78364337 0.78364337]]

#pandas solution
m = pd.concat([df['column']] * len_A, axis=1)
print (m)
     column    column    column
0  0.902062  0.902062  0.902062
1  0.557808  0.557808  0.557808
2  0.655985  0.655985  0.655985
3  0.832471  0.832471  0.832471
4  0.199884  0.199884  0.199884
5  0.127254  0.127254  0.127254
6  0.771439  0.771439  0.771439
7  0.432289  0.432289  0.432289
8  0.385282  0.385282  0.385282
9  0.783643  0.783643  0.783643

m = np.isclose(a, b=A, atol=0.004)
print (m)
[[False False  True]
 [False False False]
 [False False False]
 [False False False]
 [False False False]
 [False False False]
 [False False False]
 [ True False False]
 [False False False]
 [False  True False]]

最后通过any获取每行带有True的所有值:

print (m.any(axis=1))
[ True False False False False False False  True False  True]

最后按boolean indexing过滤:

print (df[m.any(axis=1)])
     column
0  0.902062
7  0.432289
9  0.783643

【讨论】:

  • 嗨,Jezrael,我已经提供了示例数字(借用了你的一些数字!)并试图更好地解释我在这个问题中要做什么。
  • @Neko - 是的,更动态的我的代码应该是a = np.broadcast_to(df['column'].values[:, None], (len(df),len(A)))
  • @Neko - 所以需要匹配 0.4320.7830.902 ?我按A 的长度为动态重复列添加代码。还是缺少什​​么?
  • 嘿,Jezrael,我刚刚对其进行了测试,效果非常好!但是,我不确定如何使用布尔“True”和“False”返回从数据框中提取实际数值(以及原始行)(我确信这很简单,我只是一个大菜鸟涉及到编码 D:)...
  • 打败我哈哈!谢谢^^!
猜你喜欢
  • 2020-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-21
  • 2021-07-19
  • 1970-01-01
  • 2017-01-07
  • 1970-01-01
相关资源
最近更新 更多