我有一个 DataFrames 字典,其中的键是指数据的年份。我想遍历字典并对数据帧进行修改。我对 dfs 的列名和内容进行了修改。
for year, df in df_data.items():
cols = df .columns
new_cols = [re.sub(r'\s\d{4}\-\d{2}', '', c) for c in cols]
df.columns = new_cols
for year, df in df_data.items():
df['Date'] = pd.to_datetime(df['Date'], infer_datetime_format=True)
df = df.drop_duplicates(subset='Id', keep='first')
Run Code Online (Sandbox Code Playgroud)
有人可以向我解释这样做的行为吗?特别是 dfs 如何存储在内存中以及为什么列的重命名有效但对内容的修改无效。另外,有没有最好的方法来做到这一点,要么复制 df,然后在 dict 索引中替换它,要么不断更改 df_data[year] 引用?
正如 @juanpa.arrivillaga 上面所描述的,drop_duplicates 返回一个 dataframe,您将其分配给局部变量df。考虑以下示例:
a = [0, 1]
for b in a:
print(f'b: {b}')
b = 2
print(f'b: {b}')
print(f'a: {a}')
Run Code Online (Sandbox Code Playgroud)
这是输出:
b: 0
b: 2
b: 1
b: 2
a: [0, 1]
Run Code Online (Sandbox Code Playgroud)
您可以看到局部变量b被赋值为 value ,但循环完成后2列表没有变化。a这是因为b是对列表的引用,而不是列表本身。分配b = 2会导致b更改为对整数的引用2,但不会导致引用的列表项b更改为对整数的引用2。在第一个循环开始时,引用如下所示:
b -> a[0] -> the integer 0
Run Code Online (Sandbox Code Playgroud)
分配b = 2结果如下:
a[0] -> the integer 0
b -> the integer 2
Run Code Online (Sandbox Code Playgroud)
不是这个:
b -> a[0] -> the integer 2
Run Code Online (Sandbox Code Playgroud)
要在循环中改变对象,您必须仅使用就地工作的方法,或者必须使用对该对象的直接引用:
for year in df_data.keys():
cols = df[year].columns
new_cols = [re.sub(r'\s\d{4}\-\d{2}', '', c) for c in cols]
df[year].columns = new_cols
for year in df_data.keys():
df[year]['Date'] = pd.to_datetime(df[year]['Date'], infer_datetime_format=True)
df[year] = df[year].drop_duplicates(subset='Id', keep='first')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
152 次 |
| 最近记录: |