为什么pandas以不同方式处理日期时间索引?

时间:2015-08-21 13:36:56

标签: python pandas

Pandas乘法不能像我期望的那样对列数据帧起作用:

In [1]: import pandas as pd

In [2]: df = pd.DataFrame({'a': [1,2,3]})

In [3]: s = pd.Series([5,6,7])

In [4]: df * s

    0   1   2   a
0 NaN NaN NaN NaN
1 NaN NaN NaN NaN
2 NaN NaN NaN NaN

this question中所述,正确的方法是specify the axis

In [5]: df.multiply(s, axis='index')

    a
0   5
1  12
2  21

但是,对于具有日期时间索引的数据帧,这是不必要的:

In [6]: import numpy as np

In [7]: days = np.arange('2000-12-20', '2000-12-23', dtype='datetime64[D]')

In [8]: df = pd.DataFrame({'a': [1,2,3]}, index=days)

In [9]: s = pd.Series([5,6,7], index=days)

In [10]: df * s

             a
2000-12-20   5
2000-12-21  12
2000-12-22  21

这是为什么?为什么第一个示例不起作用,是否可以始终使用*而不是.multiply

2 个答案:

答案 0 :(得分:3)

看起来这是旧的弃用行为。问题here。在这两种情况下都可能最明确。

In [161]: pd.__version__
Out[161]: '0.16.2'

In [160]: df * s
....: FutureWarning: TimeSeries broadcasting along DataFrame index by default is deprecated. Please use DataFrame.<op> to explicitly broadcast arithmetic operations along the index
  FutureWarning)
Out[160]: 
             a
2000-12-20   5
2000-12-21  12
2000-12-22  21

答案 1 :(得分:1)

要回答您的其他问题,您可以在绝大多数情况下(可能全部)使用*代替.multiply,但这是否是一个改进可能是一个不同的问题。您可能最好将运算符视为addsub等方便的快捷方式,但这并不总是最好的方法。

无论如何,如果你想在这里使用*,你可以做以下任何事情:

df['a'] * s                    # convert df to series

df * pd.DataFrame(s).values    # convert s to dataframe then to array

df * s.values.reshape(3,1)     # convert s to numpy array

第一个是非常明显的,你只需要设置两个系列,然后事情就像你想要的那样。请注意,这比将两者都转换为数据帧更容易,因为在乘以序列时只需要索引(axis = 0)就可以对齐,但是在乘以数据帧时需要索引和列(轴= 1)对齐。虽然你可以通过给你的系列提供与你希望乘以的数据帧列相同的名称来解决这个问题。

第二种和第三种方式更有趣和一般。他们通过转换为numpy数组来摆脱索引。这样做可以让你自由地做很多不同的事情,但请记住,因为你明确地忽略了索引,所以它可能很危险,这意味着你要确保它们正确排列。

另请注意,一般情况下,您可以使用.values.shape来更好地了解当您尝试乘法,除法等时的尺寸。通常当这些操作失败时,快速检查形状将会告诉你原因。