我现在想知道我的csv文件包含的头的数量(在0到~50之间)。文件本身是巨大的(因此不读取完整的文件是强制性的),并包含数值数据。我知道csv。Sniffer有一个has_header()函数,但它只能检测1个头。我的一个想法是递归地调用has_header函数(假设它检测到第一个头),然后计算递归次数。但我相信,有一个更聪明的方法。
谷歌搜索有点痛苦,因为无论你搜索什么,如果它包含"计数"one_answers";csv"在某一时刻,您将获得csv"中的所有计数行。结果:D
澄清:与标题的数量,我的意思是行数包含的信息,这不是数据。标题没有通用规则(可以是文本、浮点数或空格),也可以是一行文本。然而数据本身只是浮点数。对我来说,这是非常清楚的,因为我已经处理这些文件很长时间了,但忘记了这不是正常情况。
我希望Numpy或Pandas有一个简单而智能的内置函数,但似乎没有。
受到目前为止评论的启发,我认为我最好的选择是
- 读取100行
- 计算每行中分隔符的个数
- 决定每行最常见的分隔符数
- 从100行的末尾开始,找到具有不同数量分隔符的第一行,或者不是浮点数。这一行是最后一行标题。
下面是查找符合特定条件的第一行的草图。出于演示目的,我使用标准"there are empty fields":
import csv
with open(filename, "r", encoding="utf-8") as handle:
for lineno, fields in enumerate(csv.reader(handle), 1):
if "" in fields:
print(lineno-1)
break
你可以更新它来寻找一些对你的数据有意义的东西,比如"第三和第八个字段包含数字":
try:
float(fields[2])
float(fields[7])
print(lineno-1)
break
except ValueError:
continue
(注意列表fields
是如何从0开始索引的,因此第一个字段是fields[0]
,第三个字段是fields[2]
),或者可能是一个更复杂的模型,其中第一行不包含空字段,连续的行包含越来越多的空字段,然后第一行包含更少的空字段:
maxempty = 0
for lineno, fields in numerate(csv.reader(handle), 1):
empty = fields.count("")
if empty > maxempty:
maxempty = empty
elif empty < maxempty:
print(lineno-1)
break
我们只是打印最后一个标题行的行号,因为你的问题问的是有多少行。也许在某些情况下,打印或返回第一行数据的编号会更有意义。
这段代码根本不使用Pandas,只使用Python标准库中的常规csv
模块。当您点击break
时,它停止读取,因此在此之后有多少行对性能无关紧要(尽管如果您需要进行实验或调试,可能只创建一个较小的文件,例如,实际文件的前200行)。
使用re.search
搜索一行中有两个或两个以上字母的行。用2代替1,不算作标头科学符号(例如,1.0e5
)。
# In the shell, create a test file:
# echo "foo,barnbaz,bletchn1e4,2.0n2E5,2" > in_file.csv
import re
num_header_lines = 0
for line in open('in_file.csv'):
if re.search('[A-Za-z]{2,}', line):
# count the header here
num_header_lines += 1
else:
break
print(num_header_lines)
# 2
嗯,我认为你可以得到csv文件的第一行,然后用","分隔它。它将返回一个包含所有header的数组。现在你可以用len来计数了。
试试这个:
import pandas as pd
df = pd.read_csv('your_file.csv', index_col=0)
num_rows, num_cols = df.shape
既然我知道你担心文件大小,把文件分成几块就可以了:
chunk_size = 10000
df = pd.read_csv(in_path,sep=separator,chunksize=chunk_size,
low_memory=False)
我认为你可能会得到一个可变的行数,如果你读df块逐块,但如果你只感兴趣的列数,这将很容易工作。
您也可以查看dask.dataframe
这只读取csv的第一行
import csv
with open('ornek.csv', newline='') as f:
reader = csv.reader(f)
row1 = next(reader)
sizeOfHeader = len(row1)