首页 > 解决方案 > Pandas 对象列表上的循环表现出奇怪的行为

问题描述

当谈到 Pandas 对象及其循环列表时,我遇到了一个轻微的问题。在我正在处理的一些代码中,有一些 pandas 数据帧被放置在一个列表中,因此可以对所有这些数据帧执行操作。

但是,我注意到某些操作,例如创建新列,在“天真” Python 中工作for loops,而其他操作,例如反转数据帧的顺序,

  1. 需要显式索引,并且
  2. 不影响原始数据框(仅它们位于列表中的副本)。

我正在寻求帮助,以使我的 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])

标签: pythonpandasloopsdataframeshallow-copy

解决方案


第一个操作dataframe['date_time']=表明它是就地操作,而不是assignment

在第二个操作中,第二种方法起作用的原因是,当您遍历一个不使用索引的列表时,您创建了一个与列表无关的新变量,并将其分配给一个新值。

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引用或指向一个新变量。

这里的问题是您(或我们)混淆了就地操作与分配。


推荐阅读