当涉及到 Pandas 对象及其循环的列表时,我遇到了一个轻微的头疼问题。在我正在编写的一些代码中,有一些 pandas 数据帧被放入一个列表中,因此可以对所有数据帧执行操作。
但是,我注意到某些操作(例如创建新列)在“天真的”Python for 循环中工作,而其他操作(例如反转数据帧的顺序)
- 需要显式索引,并且
- 不影响原始数据帧(仅影响其驻留在其中的副本) 列表)。
我正在寻求帮助,以使我的 MWE 的第二部分像第一部分一样轻松地工作,并深入了解首先导致这种差异的底层逻辑。
## Creating data
import pandas as pd
from io import StringIO
data = StringIO(
"""
date;time;random
2019-06-12;19:59:59+00:00;99
2019-06-12;19:59:54+00:00;200
2019-06-12;19:59:52+00:00;65
2019-06-12;19:59:34+00:00;140
"""
)
df = pd.read_csv(data, sep=";")
print(df)
## Creating list; there is only one dataframe in this list to make the
## code easier to work with, but in actuality I am working with >20 dataframes
df_list = [df]
## First operation - successfully adds new column to both original df and df_list[0]
for dataframe in df_list:
dataframe['date_time'] = pd.to_datetime(dataframe['date']+' '+dataframe['time'], utc=True)
print(df)
print(df_list[0])
## Second operation - successful only if using explicit indexing over list, first commented segment does nothing;
## using second segment works, but does not effect original df, only df_list[0].
# for dataframe in df_list:
# dataframe = dataframe.iloc[::-1]
# dataframe.reset_index(drop=True, inplace=True)
for i in range(len(df_list)):
df_list[i] = df_list[i].iloc[::-1]
df_list[i].reset_index(drop=True, inplace=True)
print(df)
print(df_list[0])
最佳答案
第一次操作,dataframe['date_time']=
表明这是一个就地操作,而不是赋值。
之所以在第二个操作中,第二种方法有效,是因为当您循环遍历不使用索引的列表时,您创建了一个与列表无关的新变量,并将其分配给一个新值。
a = [1,2,3]
for i in a:
i = 0
print(a)
print(i)
输出为:
[1, 2, 3]
0
所以在你的情况下,当你 for dataframe in df_list:
,您创建一个新变量 dataframe
,引用或指向 df_list
中每个元素的地址。然后,当您将它们分配给反转的数据框时,dataframe
引用或指向一个新变量。
这里的问题是你(或我们)混淆了就地操作与赋值。
关于python - 循环 Pandas 对象列表表现出奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58830203/