【发布时间】:2019-10-20 13:01:33
【问题描述】:
我有一列日期时间,需要将其中几个值更改为新的日期时间。当我使用 df.loc[indices, 'col'] = new_datetimes 设置值时,未受影响的值被强制为 int,而新的设置值在日期时间中。如果我一次设置一个值,则不会发生类型强制。
为了说明,我创建了一个只有一列的示例 df。
df = pd.DataFrame([dt.datetime(2019,1,1)]*5)
df.loc[[1,3,4]] = [dt.datetime(2019,1,2)]*3
df
这会产生以下结果: output
如果我单独更改索引 1、3、4:
df = pd.DataFrame([dt.datetime(2019,1,1)]*5)
df.loc[1] = dt.datetime(2019,1,2)
df.loc[3] = dt.datetime(2019,1,2)
df.loc[4] = dt.datetime(2019,1,2)
df
我得到正确的输出: output
建议在设置之前将列表转换为 numpy 数组,这确实解决了问题。但是,如果您尝试使用 numpy 数组设置多个列(其中一些不是日期时间),则问题再次出现。
在此示例中,数据框有两列,我尝试设置这两列。
df = pd.DataFrame({'dt':[dt.datetime(2019,1,1)]*5, 'value':[1,1,1,1,1]})
df.loc[[1,3,4]] = np.array([[dt.datetime(2019,1,2)]*3, [2,2,2]]).T
df
这给出了以下输出: output
有人可以解释导致强制的原因以及如何防止它这样做吗?我编写的使用它的代码是一个多月前编写的,并且过去运行得很好,这可能是关于未来版本的熊猫弃用某些功能的警告之一吗?
非常感谢您对正在发生的事情进行解释,因为我编写了可能使用类似功能的其他代码,希望确保一切按预期工作。
【问题讨论】:
-
根据我尝试使用数据框而不是列表/数组设置的建议,它设置了两列而没有强制。
df.loc[[1,3,4]] = pd.DataFrame({'dt':[dt.datetime(2019,1,1)]*3, 'value':[2,2,2]}, index=[1,3,4])我想我会回到我写的代码并在设置之前将所有数组转换为数据帧。有谁知道不使用数据帧时强制的原因? -
您以不必要的方式分配值。
df.loc[[1,3,4]] = dt.datetime(2019,1,2), 2返回正确的输出而不做任何更改。使用 .loc 如果它们都将更改为相同的输出,则无需匹配输入的长度。 -
第二件事:1546300800000000000实际上是2019/1/1作为int的表示。
pd.to_datetime(1546300800000000000)您可以看到将其转换回其日期时间格式。由于您设置它的方式,它将它转换为一个对象,并将 dt 转换为 int 版本。 -
我想我应该让示例变得更复杂。为方便起见,我为三行设置了相同的值,但在实际应用程序中,行是不同的。我知道 int 实际上代表日期时间。令我困惑的是为什么 df.loc[1,3,4] = array 会导致强制,而 df.loc[1,3,4] = dataframe type 不会。