我有一个包含320k行和450列的小型数据帧。有一些列号包含列号:
list1 = [1,3,5,...]
list2 = [4,9,...]
...
我的目标是从当前列表中替换每列中的某些值,然后保存它:
df[df[list1] > 7] = np.nan
df[df[list2] >90] = np.nan
...
数据框的大小让我按块进行:
for chunk in pd.read_csv(filePrev,chunksize=10000,header=None):
>>> chunk[chunk[list1] >= 7] = np.nan
>>> chunk[chunk[list2] >= 90] = np.nan
...
>>> chunk.to_csv(newFile,mode='a',header=False,index=False)
但是有一个不正确的工作:我已多次运行此代码,并且它大部分无法完成工作(IPython中的内存错误或Windows关闭的应用程序),具有任何chunksize值。但是当它完成时,它在大多数字符串中将所有值替换为NaN,并且存在一些字符串,其中所有字符串都被正确替换。
我在相同数据集的小块上尝试了相同的逻辑,它可以正常工作!
In [11]: df = pd.read_csv(filePrev,nrows=5,usecols=[1,2,3,4,5,6,7],header=None)
In [12]: df
Out[12]:
1 2 3 4 5 6 7
0 1 1 1 1 1 1 1
1 3 1 1 1 2 1 1
2 3 1 1 1 1 1 1
3 3 1 1 1 2 1 2
4 3 1 1 1 1 1 1
In [13]: list = [1,7]
In [14]: df[df[list] > 1] = np.nan
In [15]: df
Out[15]:
1 2 3 4 5 6 7
0 1 1 1 1 1 1 1
1 NaN 1 1 1 2 1 1
2 NaN 1 1 1 1 1 1
3 NaN 1 1 1 2 1 NaN
4 NaN 1 1 1 1 1 1
那么,关于它的任何想法?我们可以在“分块”模式下实现它,还是有另一种方式(那么我需要一个例子)?我只想将某些值替换为NaN ...:)
答案 0 :(得分:1)
这可以通过保持文件打开来改进,而不是每次在追加模式下打开文件:
with open(newFile, 'a') as f:
for chunk in pd.read_csv(filePrev,chunksize=10000,header=None):
chunk[chunk[list1] >= 7] = np.nan
chunk[chunk[list2] >= 90] = np.nan
chunk.to_csv(f, header=False, index=False)
最近有人在这里报告了这种行为,这次更改在Windows上给了他们a 98.3% performance gain(我在osx上只看到了大约25%)。
如果你使用Profile或(ipython' s)%prun运行你的python代码,你可以看到被调用的时间和函数调用次数最多。在question I was referring to above的情况下,花费在python的close
函数上的时间最多(每次调用pd.read_csv
后关闭,除非您保持文件打开。)
注意:逻辑看起来没问题,您没有分配给副本。正如您在较小的示例中所看到的:代码有效!
答案 1 :(得分:1)
问题在于代码处理某些列。有这样的字符串:
chunk[chunk[393] > 50] = np.nan
而不是
chunk[chunk[[393]] > 50] = np.nan
如果有N:
chunk [393] [N]> 50
然后所有行都转换为带NaN的数组
感谢大家的帮助。