【问题标题】:How do numpy functions operate on pandas objects internally?numpy 函数如何在内部对 pandas 对象进行操作?
【发布时间】:2017-10-07 12:22:58
【问题描述】:

Numpy 函数,例如 np.mean()、np.var() 等,接受类似数组的参数,例如 np.array 或 list 等。

但传入 pandas 数据框也可以。这意味着 pandas 数据框确实可以将自己伪装成一个 numpy 数组,我觉得这有点奇怪(尽管知道 df 的底层值确实是 numpy 数组)。

对于一个类似于数组的对象,我认为它应该可以使用整数索引进行切片,就像切片 numpy 数组一样。因此,例如 df[1:3, 2:3] 应该可以工作,但会导致错误。

因此,当数据框进入函数内部时,可能会转换为 numpy 数组。但如果是这样的话,为什么 np.mean(numpy_array) 会导致与 np.mean(df) 不同的结果?

a = np.random.rand(4,2)
a
Out[13]: 
array([[ 0.86688862,  0.09682919],
   [ 0.49629578,  0.78263523],
   [ 0.83552411,  0.71907931],
   [ 0.95039642,  0.71795655]])

np.mean(a)
Out[14]: 0.68320065182041034

给出的结果与下面给出的不同......

df = pd.DataFrame(data=a, index=range(np.shape(a)[0]), 
columns=range(np.shape(a)[1]))

df
Out[18]: 
      0         1
0  0.866889  0.096829
1  0.496296  0.782635
2  0.835524  0.719079
3  0.950396  0.717957

np.mean(df)
Out[21]: 
0    0.787276
1    0.579125
dtype: float64

前一个输出是单个数字,而后者是按列的平均值。 numpy 函数如何知道数据框的构成?

【问题讨论】:

  • 要使用底层数组数据,我们需要使用.values。没有它,它就不完全是数组数据。结果应该与 NumPy funcs 一致。

标签: python pandas numpy


【解决方案1】:

如果你逐步完成:

--Call--
> d:\winpython-64bit-3.4.3.5\python-3.4.3.amd64\lib\site-packages\numpy\core\fromnumeric.py(2796)mean()
-> def mean(a, axis=None, dtype=None, out=None, keepdims=False):
(Pdb) s
> d:\winpython-64bit-3.4.3.5\python-3.4.3.amd64\lib\site-packages\numpy\core\fromnumeric.py(2877)mean()
-> if type(a) is not mu.ndarray:
(Pdb) s
> d:\winpython-64bit-3.4.3.5\python-3.4.3.amd64\lib\site-packages\numpy\core\fromnumeric.py(2878)mean()
-> try:
(Pdb) s
> d:\winpython-64bit-3.4.3.5\python-3.4.3.amd64\lib\site-packages\numpy\core\fromnumeric.py(2879)mean()
-> mean = a.mean

您可以看到type 不是ndarray,因此它会尝试调用a.mean,在本例中为df.mean()

In [6]:

df.mean()
Out[6]:
0    0.572999
1    0.468268
dtype: float64

这就是输出不同的原因

上面重现的代码:

In [3]:
a = np.random.rand(4,2)
a

Out[3]:
array([[ 0.96750329,  0.67623187],
       [ 0.44025179,  0.97312747],
       [ 0.07330062,  0.18341157],
       [ 0.81094166,  0.04030253]])

In [4]:    
np.mean(a)

Out[4]:
0.52063384885403818

In [5]:    
df = pd.DataFrame(data=a, index=range(np.shape(a)[0]), 
columns=range(np.shape(a)[1]))
​
df

Out[5]:
          0         1
0  0.967503  0.676232
1  0.440252  0.973127
2  0.073301  0.183412
3  0.810942  0.040303

numpy 输出:

In [7]:
np.mean(df)

Out[7]:
0    0.572999
1    0.468268
dtype: float64

如果您调用 .values 来返回一个 np 数组,那么输出是相同的:

In [8]:
np.mean(df.values)

Out[8]:
0.52063384885403818

【讨论】:

  • 您能解释一下为什么通常 numpy 函数在传递数据帧时似乎可以工作吗?例如np.split 工作..这些只是一种情况,还是有与 numpy pandas 集成的一般哲学?
  • @Alex numpy 函数将在 pandas 结构上调用 __array__,因此任何支持此功能的东西都可以使用 numpypandas 的原始实现在下面使用 numpy 数组但后来这被重构为ndarraynumpy 仍然可以与pandas 一起正常工作
  • @EdChum 不错的答案。如果你能简单地讨论一下__array_ufunc__,那就更有价值了,这使得np.mean() 可以返回一个系列!
猜你喜欢
  • 2018-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
  • 1970-01-01
  • 2018-02-01
  • 1970-01-01
相关资源
最近更新 更多