Python / Pandas:替换大型数据集的多列中的某些值

时间:2015-05-05 01:45:32

标签: python pandas replace dataframe nan

我有一个包含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 ...:)

2 个答案:

答案 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的数组

感谢大家的帮助。