【问题标题】:How to remove columns from a file using pandas DataFrame.drop with a list of column headers read in from a second file如何使用 pandas DataFrame.drop 从文件中删除列,其中包含从第二个文件中读取的列标题列表
【发布时间】:2014-08-06 21:38:34
【问题描述】:

Python 新手和 stackoverflow 发布新手。

我的目标是创建一个 python 脚本,该脚本将获取在命令行中输入的两个文件,如果第二个文件中存在列标题,则从第一个文件中删除列,并将输出写入新文件。

我已经尝试了几种方法,目前我正在尝试使用 Pandas DataFrame.drop

在一个非常小的测试集上,我可以通过手动指定字符串中的标题来实现列的删除(感谢Delete column from pandas DataFrame),但不知道如何从文件中导入列标题列表和为 DataFrame.drop 正确格式化它们。

我有两个文件 一个大的:一百万行和多达 21,000 列的四分之一 列与样本相关,行与遗传标记相关。

我还有一个较小的文件,其中包含最多 1000 个样本 ID,它们对应于大文件中的列标题。这些与我希望从大文件中删除的列有关。

我尝试了很多事情(创建列表、创建标签),下面是一个示例,但失败了。

如果有人能指出我正确的方向,我将不胜感激。

大文件

    Name     Chr     Position     8077686010_R04C02.GType     8077686010_R04C02.X     8077686010_R04C02.Y     8131566005_R01C02.GType     8131566005_R01C02.X     8131566005_R01C02.Y
exm-rs1000026     21     38934599     NC     0.0144234     1.112413     NC     0.01250324     1.084685
exm-rs1000053     2     12790328     NC     0.04906762     1.495594     NC     0.07344548     1.552252
exm-rs1000110     9     117908721     NC     0.02433169     1.314785     NC     0.05954991     1.356415
exm-rs1000113     5     150240076     NC     0.015468     0.793373     NC     0.02498361     0.8621324
exm-rs1000158     20     36599904     NC     0.01016421     0.7593179     NC     0.4537758     0.5095596
exm-rs1000192     16     6747139     NC     0.01774782     0.8661015     NC     0.01103768     0.9004255
exm-rs1000203     14     40896108     NC     0.7707067     0.006222768     NC     0.7400684     0.003768863

较小的文件

8077686010_R04C02.GType
8077686010_R04C02.X
8077686010_R04C02.Y

输出文件

   Name     Chr     Position     8131566005_R01C02.GType     8131566005_R01C02.X     8131566005_R01C02.Y
exm-rs1000026     21     38934599     NC     0.01250324     1.084685
exm-rs1000053     2     12790328     NC     0.07344548     1.552252
exm-rs1000110     9     117908721     NC     0.05954991     1.356415
exm-rs1000113     5     150240076     NC     0.02498361     0.8621324
exm-rs1000158     20     36599904     NC     0.4537758     0.5095596
exm-rs1000192     16     6747139     NC     0.01103768     0.9004255
exm-rs1000203     14     40896108     NC     0.7400684     0.003768863

工作代码

import pandas as pd
import numpy as np

outfile = open("myout.txt", "w")

largefile = pd.read_csv('large',sep='\t',header=0,index_col=0)
largefile = largefile.astype(object)

new_data = largefile.drop(['8077686010_R04C02.GType','8077686010_R04C02.X','8077686010_R04C02.Y',], axis=1)

new_data.to_csv(outfile,sep="\t")

失败代码 - 众多代码之一

import pandas as pd
import numpy as np

outfile = open("myout.txt", "w")

largefile = pd.read_csv('large',sep='\t',header=0,index_col=0)
largefile = largefile.astype(object)

dropcols = open("smallerfile",'r').read().split('\n')
new_data = largefile.drop(dropcols, axis=1)

new_data.to_csv(outfile,sep="\t")

列表生成

['8131566005_R01C02.GType', '8131566005_R01C02.X', '8131566005_R01C02.Y', '8131566013_R02C01.GType', '8131566013_R02C01.X', '8131566013_R02C01.Y', '']

输出

Traceback (most recent call last):
File "my.py", line 59, in <module>
new_data = largefile.drop(dropcolslst, axis=1)
File "/usr/lib/pymodules/python2.7/pandas/core/generic.py", line 174, in drop
new_axis = axis.drop(labels)
File "/usr/lib/pymodules/python2.7/pandas/core/index.py", line 881, in drop
raise ValueError('labels %s not contained in axis' % labels[mask])
ValueError: labels ["] not contained in axis

【问题讨论】:

  • 我会确保在 read() 之后和 split() 之前剥离()第一行
  • 谢谢。我不知道该怎么做。有没有更高效的方法来实现列删除?我的笔记本电脑出现内存问题。

标签: python-2.7 numpy pandas multiple-columns


【解决方案1】:

要让您的代码正常工作,您只需从 dropcols 列表中删除空字符串即可。像这样的:

dropcols = [x for x in dropcols if x != '']

如果您想处理 dropcols 列表有效的情况,即使您指定的列不在较大的数据框中,您也可以执行类似的操作 - 将 dropcols 与数据框中的列相交。

dropcols = set(dropcols) & set(largefile.columns)

【讨论】:

  • 非常感谢您提供这两种解决方案 - 我花了几天时间试图让它工作 - 我想知道空字符串 - 但我认为问题与数据结构有关。
  • +1 表示交集方法!在较小文件中的 ID 不能保证在大文件的列标题中的情况下保持可用性的好方法。
【解决方案2】:

执行此操作的内存效率更高的方法。关键是在pd.read_csv中申请usecols

import pandas as pd
import numpy as np
dropcols = open("smallerfile",'r').read().split('\n')
cols = open("large",'r').read().rstrip().split('\t')
usecols = [ i for i in range(cols) if cols[i] not in dropcols]

告诉pd.read_csv 只加载usecols 并将日期类型指定为object。 接下来保存加载的文件。

largefile = pd.read_csv('large',sep='\t',header=0,index_col=0, usecols=usecols, dtype='object')
with open("myout.txt", "w") as outfile:
    largefile.to_csv(outfile,sep="\t")

【讨论】:

  • 非常感谢,我会试试看的。为了处理它们,我不得不将文件分成可管理的块,否则使用 awk 删除列。
猜你喜欢
  • 1970-01-01
  • 2016-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多