带或不带广播的Pandas数据框乘法

4
I have 2 dataframes:

>>> type(c)
Out[118]: pandas.core.frame.DataFrame
>>> type(N)
Out[119]: pandas.core.frame.DataFrame

>>> c
Out[114]: 
                       t
2017-06-01 01:06:00 1.00
2017-06-01 01:13:00 1.00
2017-06-01 02:09:00 1.00
2017-06-26 22:47:00 1.00

>>> N
Out[115]: 
                       0    1
2017-06-01 01:06:00 1.00 1.00
2017-06-01 01:13:00 1.00 1.00
2017-06-01 02:09:00 1.00 1.00
2017-06-26 22:47:00 1.00 1.00

我需要将这些列相乘,以获得一个 4x2 的数据框,其中每列都是 N 中对应元素与 C 相乘的结果。我尝试了以下 4 种方法,但都没有成功:

>>> N.multiply(c, axis='index')
Out[116]: 
                      0   1   t
2017-06-01 01:06:00 nan nan nan
2017-06-01 01:13:00 nan nan nan
2017-06-01 02:09:00 nan nan nan
2017-06-26 22:47:00 nan nan nan

>>> c[:]*N
Out[98]: 
                      0   1   t
2017-06-01 01:06:00 nan nan nan
2017-06-01 01:13:00 nan nan nan
2017-06-01 02:09:00 nan nan nan
2017-06-26 22:47:00 nan nan nan

>>> c*N
Out[99]: 
                      0   1   t
2017-06-01 01:06:00 nan nan nan
2017-06-01 01:13:00 nan nan nan
2017-06-01 02:09:00 nan nan nan
2017-06-26 22:47:00 nan nan nan

>>> c[:, None]*N
Traceback (most recent call last):

  File "C:\...pandas\core\frame.py", line 1797, in __getitem__
    return self._getitem_column(key)
  File "C:\...core\frame.py", line 1804, in _getitem_column
    return self._get_item_cache(key)
  File "C:\...core\generic.py", line 1082, in _get_item_cache
    res = cache.get(item)
TypeError: unhashable type

有没有一种简单的方式,在广播或不广播的情况下都可以轻松地做到这一点?

1
注意:c[:, None] 这种添加新轴的表示法是针对numpy数组的 - 它不能用于数据框。如果您想要添加一个新轴,首先需要使用 c.values[:, None] 将其转换为numpy数组。 - ayhan
1个回答

5
问题在于您传递了一个DataFrame,因此它尝试匹配列名。如果您切片列t,它将变为一个Series,并且会适当地广播:
N.mul(c['t'], axis=0)
Out: 
                       0    1
2017-06-01 01:06:00  1.0  1.0
2017-06-01 01:13:00  1.0  1.0
2017-06-01 02:09:00  1.0  1.0
2017-06-26 22:47:00  1.0  1.0

对于numpy数组,您不需要指定任何内容。对于形状为(4,2)和(4,1)的数组,numpy会看到具有相同长度的轴并进行广播。

请考虑以下数据框:

N
Out: 
                       0    1
2017-06-01 01:06:00  1.0  2.0
2017-06-01 01:13:00  6.0  5.0
2017-06-01 02:09:00  4.0  3.0
2017-06-26 22:47:00  4.0  7.0


c
Out: 
                       t
2017-06-01 01:06:00  6.0
2017-06-01 01:13:00  2.0
2017-06-01 02:09:00  8.0
2017-06-26 22:47:00  2.0

你可以通过 .values 属性访问底层数组。
N.values * c.values
Out: 
array([[  6.,  12.],
       [ 12.,  10.],
       [ 32.,  24.],
       [  8.,  14.]])

将会给你相同的结果,就像

N.mul(c['t'], axis=0)
Out: 
                        0     1
2017-06-01 01:06:00   6.0  12.0
2017-06-01 01:13:00  12.0  10.0
2017-06-01 02:09:00  32.0  24.0
2017-06-26 22:47:00   8.0  14.0

但由于整个操作都是在numpy中进行的,因此您将失去标签。


谢谢,这很有帮助。只是为了完全理解这个概念,如果“N”是一个ndarray(4X2),而“c”是一个数据框,你认为正确的方法是什么?我需要先将N转换为数据框吗?在那种情况下,我尝试过Nc[:]和Nc['t'],但没有成功。 - dayum
@ayhan 你好,当我尝试使用 N * c['t'] 时它无法工作,你知道为什么吗? - malioboro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接