我对熊猫有一个非常奇怪的问题 - 我正在尝试从数据框中提取一列值以进行下游分析。我编写的脚本一次迭代许多文件来执行此操作。每个文件都是使用bam-readcounts上的相同命令创建的,包含用于DNA测序运行的读取深度数据。
有时,它像梦一样工作,并返回我需要它返回的所有内容,其他人收到错误信息:
TypeError: cannot do slice indexing on <class 'pandas.core.indexes.base.Index'> with these indexers [310] of <class 'int'>
该列肯定包含整数 - 我已经尝试使用浮点运行脚本并且使用str只是为了确定。
我甚至有过这样的实例,我在几分钟之内分析了同一组文件,而没有更改我的脚本代码,并且让pandas返回错误消息。我有过这样的实例,我用bam-headcount分析了同时创建的两批文件,并让它在一个批次上返回错误消息,而不是另一个。
相关的代码是:
col_names = ['Col_' + str(i) for i in range(1, max_col_nr)]
df = pd.read_csv(myFile, sep = '\t', names = col_names)
df2 = df.set_index("Col_2", drop = False)
df3 = (df2.loc[310:400,"Col_4"])
US_Av = (int(round(df4.mean())))
我从未遇到过这样的情况,即相同的代码会在运行中改变其行为,如果有人有任何建议,我将非常感激。这让我有些疯狂。
示例数据供以下参考。这是我试图获得平均值的第四列。
GRIN2A 280 A 169
GRIN2A 281 C 169
GRIN2A 282 C 172
GRIN2A 283 T 171
答案 0 :(得分:0)
我想我已经知道了 - 你和dtype的关系正确。在失败的文件中,pandas错误地标记了列。 pd的正确结果应该是
df =
Col_1 Col_2 Col_3 Col_4
0 GRIN2A 280 A 44
1 GRIN2A 281 C 44
2 GRIN2A 282 C 44
对于某些文件,相同的代码会导致
df =
Col_1 Col_2 Col_3
GRIN2A 280 A 46
GRIN2A 281 A 46
GRIN2A 282 A 46
这意味着,对于发生这种情况的文件,索引的Col_2是str而不是int,导致错误消息。
对于我的生活,我仍然无法解决为什么大熊猫在某些文件中错误地标题列,而不是其他文件(每次迭代超过300个文件时为2或3)。这些文件的格式相同,并通过在我的已排序的bam文件上运行相同的bam-readcount迭代器来创建。
包含pandas的代码也由迭代器运行,因此对于每个文件都是相同的。
我可以使用类似的东西......
if Col2 is (int):
elif Col1 is (int):
有点笨拙并且没有解决根本问题,但至少我不会丢失错误的文件中的数据。如果有人有任何想法为什么会发生这种情况,我很乐意听到评论。
感谢您帮助RCA
答案 1 :(得分:0)
您可以通过几种方式明确设置dtypes
,这样可以避免使用if语句。
第一个是在读取文件时设置类型,如下所示:
df = pd.read_csv(myFile,
sep = '\t',
names = col_names,
dtype = {<column name>: np.int32, ...}) # note that you'll need numpy imported
这显然只有在您提前了解列的类型时才有效。 read_csv
的文档有更多信息 - 您也可以设置一些列,或者告诉pandas跳过整个文件的解释(如果您尝试以下选项,您想要做的事情)。
下一个选项是使用to_numeric
,它会在将其作为索引之前强制执行该系列。这可能是最简单的方法。
df = pd.read_csv(myFile, sep = '\t', names = col_names)
df["Col_2"] = pd.to_numeric(df["Col_2"])
df2 = df.set_index("Col_2", drop = False)
df3 = (df2.loc[310:400,"Col_4"])
US_Av = (int(round(df4.mean())))
然后,最后,单行版本:
df = pd.read_csv(myFile, sep = '\t', names = col_names)
df2 = df.set_index(df.Col_2.as_type(int), drop = False)
df3 = (df2.loc[310:400,"Col_4"])
US_Av = (int(round(df4.mean())))