【发布时间】:2014-01-28 19:51:51
【问题描述】:
我最近将 Pandas 更新到 v0.13.0,它似乎引入了日期时间类型数据的问题。
让我们以这个例子为例,我们有一个数据框,其中一列 datetime64[ns] 和一列 int32。
import pandas as pd
import numpy as np
t = pd.date_range('2000-01-01','2000-01-20')
v = np.arange(0,len(t))
df = pd.DataFrame({'date':t,'val':v})
首先,让我们将每一列设置为相同数据类型的标量值。
# SETTING SCALAR OF SAME TYPE
df.loc[:,'val'] = v[0] # Works fine
df.loc[:,'date'] = t[0] # Works fine
Pandas 正确地广播数据。任何一列都没有问题。
其次,让我们尝试用不同数据类型的标量替换:
# SETTING SCALAR, BUT OF DIFFERENT DTYPE
df.loc[:,'val'] = t[0] # Works fine
df.loc[:,'date'] = v[0] # Does not work?
虽然第一次操作成功,但第二次给出错误: "ValueError: 新类型与数组不兼容。"
第三,让我们尝试用一个数据向量替换每一列(不改变数据类型):
df = pd.DataFrame({'date':t,'val':v})
# SETTING VECTOR
df.loc[:,'val'] = v * 2 # Works fine
df.loc[:,'date'] = t.shift(365) # Does not work?
再次,第一个操作有效。但第二次操作失败,出现错误: "ValueError: 多元素数组的真值不明确。使用a.any() 或a.all()"
有人知道这里发生了什么吗?这可能是两个不同的问题。感谢您的帮助!
编辑:感谢 Jeff 为上述问题提供正确答案。然而,他的回答确实提出了一个(希望如此)最后一个问题:
如何分配给 DataFrame 的子集,其中子集跨越多行和多列,并且至少有一列是 datetime64 类型?
例如:
t = pd.date_range('2000-01-01','2000-01-20')
v = np.arange(0,len(t))
df = pd.DataFrame({'date':t,'val':v,'val2':v})
# USING LABELS
df.loc[4:7,['val','val2']] = df.loc[4:7,['val','val2']] # Works fine
df.loc[4:7,['date','val']] = df.loc[4:7,['date','val']] # Does not work?
# USING ROW SLICE
df[4:7] = df[4:7] # Does not work?
# USING BOOLEAN ROW MASK
mask = np.array([True] * len(df))
mask[[1,4,8]] = False
df[mask] = df[mask] # Does not work?
虽然 Jeff 使用 df[col] = val 而不是 df.loc[:,col] = val 的解决方案正确解决了我原来的问题(列分配),但它对基于行(或行 x 列)没有帮助-based) 分配。*
- 除非你转置 df.T[[4,5,6]] = df.T[[4,5,6]],但这似乎是作弊...
谢谢。
【问题讨论】:
-
原来最后一个问题是由于一个错误,该错误将在即将发布的版本中修复。
标签: python datetime numpy pandas