【问题标题】:Python/Pandas: replacing certain values in multiple columns of large datasetPython/Pandas:替换大型数据集多列中的某些值
【发布时间】:2015-07-14 14:16:32
【问题描述】:

我有一个包含 320k 行和 450 列的小型数据框。有一些带有列号的列表:

list1 = [1,3,5,...]
list2 = [4,9,...]
...

我的目标是从当前列表中替换每列中的某些值,然后保存它:

df[df[list1] > 7] = np.nan
df[df[list2] >90] = np.nan
...

dataframe 的大小让我不得不分块做:

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 ... :)

【问题讨论】:

标签: python pandas replace dataframe nan


【解决方案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 的)%prun 运行您的 python 代码,您可以看到被调用最多的时间和最多的函数调用。在question I was referring to above 的情况下,大部分时间花在python 的close 函数上(每次调用pd.read_csv 后关闭,除非您保持文件打开。)


注意:逻辑看起来没问题,您没有分配给副本。正如您在较小的示例中看到的那样:代码有效!

【讨论】:

    【解决方案2】:

    问题在于代码处理某些列。有这样的字符串:

    chunk[chunk[393] > 50] = np.nan
    

    代替

    chunk[chunk[[393]] > 50] = np.nan
    

    如果有N个:

    块[393][N] > 50

    然后将所有行转换为 NaN 数组


    感谢大家的帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-19
      • 2018-02-26
      • 2022-07-08
      • 2016-03-29
      • 2017-07-09
      • 1970-01-01
      • 2020-10-29
      • 2018-07-30
      相关资源
      最近更新 更多