在工作中,我遇到了一些关于熊猫DF和append的奇怪行为
目标是生成一个行数为RowNum
的DF,重复UniqueInt
值,并生成一个从UniqueInt
+1开始到RowNum
的新的连续数字列。这是一种用相同的先前数据填充中间的空数据的方法
我主要关心的不是如何实现这一点,而是为什么在将结果追加到空数据帧时,结果数据与代码的输出不一致(即:追加会更改所追加数据的值)
这是在Python3.7.4上实现的
我创建了一个非常小的可复制示例:
import pandas as pd
import numpy as np
#Create a DF
TemporalDF=pd.DataFrame([2,2,3,3,3,7,7,7,8,8,8,9,9,10,10,10])
TemporalDF.columns=['Int']
#Create recipients for data
BuggedResult=[]
CorrectResult=pd.DataFrame()
# For loop
for UniqueInt in range(TemporalDF['Int'].unique()[0],10):
# Specify desired number of rows
RowNum=(10-UniqueInt)
# Subset original data
Temp=TemporalDF[TemporalDF['Int']==UniqueInt]
# Fill gaps of data based on last correctly recorded data
if(Temp.shape[0]==0):
# Take last recorded value
DummyDF=DummyDF.iloc[1:DummyDF.shape[0]+1,:]
DummyDF['FillIntStart']=np.repeat(a=UniqueInt, repeats=RowNum)
else:
# Create empty data frame
DummyDF=pd.DataFrame()
# Populate
DummyDF['FillIntStart']=np.repeat(a=UniqueInt, repeats=RowNum)
DummyDF['FillIntEnd']=[UniqueInt+i for i in range(1,RowNum+1)]
# Save results
BuggedResult.append(DummyDF)
CorrectResult=CorrectResult.append(other=DummyDF, ignore_index=True)
pass
使用此代码,您可以看到有两种存储数据的方法:
BuggedResult.append()
pd.append()
方法李>BuggedResult
(BuggedResult[0]
)数组的第一个元素正常,如下所示:
┌──────────────┬────────────┐
│ FillIntStart │ FillIntEnd │
├──────────────┼────────────┤
│ 2 │ 3 │
│ 2 │ 4 │
│ 2 │ 5 │
│ 2 │ 6 │
│ 2 │ 7 │
│ 2 │ 8 │
│ 2 │ 9 │
│ 2 │ 10 │
└──────────────┴────────────┘
但是第二个元素(BuggedResult[1]
)如下所示:
┌──────────────┬────────────┐
│ FillIntStart │ FillIntEnd │
├──────────────┼────────────┤
│ 3 │ 4 │
│ 4 │ 5 │
│ 5 │ 6 │
│ 6 │ 7 │
│ 6 │ 8 │
│ 6 │ 9 │
│ 6 │ 10 │
└──────────────┴────────────┘
当它看起来像这样时(从CorrecResult表中,使用pd.append()
):
┌──────────────┬────────────┐
│ FillIntStart │ FillIntEnd │
├──────────────┼────────────┤
│ 3 │ 4 │
│ 3 │ 5 │
│ 3 │ 6 │
│ 3 │ 7 │
│ 3 │ 8 │
│ 3 │ 9 │
│ 3 │ 10 │
└──────────────┴────────────┘
换句话说,append方法是在我追加数据后更改我的数据。如果您检查代码,您还可以尝试我已经尝试过的几种方法,比如手动跟随循环,添加DummyDF.to_txt()
方法来读取单独文件中的数据,等等。逻辑似乎还可以,但当我将其附加到空数组时,结果会发生变化
这是Python3.7.4所期望的奇怪行为吗?不建议在空数组中添加DF,因为pandas已经有了解决方案,但我认为更改数据太多了
我真诚地希望这个问题是我的,因为我不是Python专家。。。那么,有什么想法吗
谢谢
我是这样做的:
如果我理解的话,这就是你想要达到的结果
我必须仔细查看您的代码,以了解它的错误。特别是,我不太明白这部分到底在做什么:
这段代码一开始就有缺陷,因为
DummyDF
在运行时可能还没有定义(仅当else:
块在前一个循环中运行时)。我有点不清楚在这种情况下你想做什么,因为它似乎在处理[2,10]范围内的缺失值,而这些值不在你原来的TemporalDF
中,我认为你没有解释在这种情况下你想做什么。您正在重用以前循环中的DummyDF
这一事实是导致错误的原因。当我在pdb(一种值得学习调试自己代码的技能)中逐步查看您的代码时,我发现这里发生了什么:因为您正在修改一个DataFrame
实例,您随后的循环最终修改了BuggedResult
列表中已经存在的同一个DataFrame
实例。DataFrame.append
不会出现这个问题,因为它会将数据复制到CorrectResult
,并在过程中调整其数据缓冲区的大小如果可能的话,我会尽量避免使用
DataFrame.append
,在我的示例中使用单个pd.concat
更有效,因为它可以为所有输出构造一个大小正确的DataFrame
,然后复制到其中一次,而不是调整每个循环上的数据大小。也许有更好的解决办法,但目前还没有想到(顺便说一句,Python有一个样式指南PEP 8关于如何格式化您的代码,这建议变量名使用小写,而CamelCase通常保留为类名。当然,不要求您使用小写,一致性最为重要。但大多数Python社区都试图遵守这些约定,因此阅读不使用小写的代码有点刺耳)
相关问题 更多 >
编程相关推荐