如何查找混合类型的输入行

时间:2017-12-15 16:20:57

标签: python pandas

我正在大熊猫的大型csv中阅读:

features = pd.read_csv(filename, header=None, names=['Time','Duration','SrcDevice','DstDevice','Protocol','SrcPort','DstPort','SrcPackets','DstPackets','SrcBytes','DstBytes'], usecols=['Duration','SrcDevice', 'DstDevice', 'Protocol', 'DstPort','SrcPackets','DstPackets','SrcBytes','DstBytes'])

我明白了:

sys:1: DtypeWarning: Columns (6) have mixed types. Specify dtype option on import or set low_memory=False.
  %!PS-Adobe-3.0

如何在输入中找到导致此警告的第一行?我需要这样做来调试输入文件的问题,输入文件不应该有混合类型。

2 个答案:

答案 0 :(得分:1)

for endrow in range(1000, 4000000, 1000):
    startrow = endrow - 1000
    rows = 1000
    try:
        pd.read_csv(filename, dtype={"DstPort": int}, skiprows=startrow, nrows=rows, header=None,
                names=['Time','Duration','SrcDevice','DstDevice','Protocol','SrcPort',
                       'DstPort','SrcPackets','DstPackets','SrcBytes','DstBytes'],
                usecols=['Duration','SrcDevice', 'DstDevice', 'Protocol', 'DstPort',
                         'SrcPackets','DstPackets','SrcBytes','DstBytes'])
    except ValueError:
        print(f"Error is from row {startrow} to row {endrows}")

将文件拆分为多个数据帧,每个数据帧各有1000行,以查看导致此问题的混合类型值的行范围。

答案 1 :(得分:1)

一旦Pandas读完文件,您就可以找出哪些行有问题(请参阅this answer了解原因)。

这意味着你应该找到一种方法你正在阅读文件。例如,逐行读取文件,并检查每一行的类型,如果它们中的任何一行与预期的类型不匹配,那么你就得到了想要的行。

要使用Pandas实现此目的,您可以将chunksize=1传递给pd.read_csv()以读取块中的文件(在这种情况下,大小为N的数据帧为1)。如果您想了解更多相关信息,请参阅documentation

代码如下:

# read the file in chunks of size 1. This returns a reader rather than a DataFrame
reader = pd.read_csv(filename,chunksize=1)

# get the first chunk (DataFrame), to calculate the "true" expected types
first_row_df = reader.get_chunk()
expected_types = [type(val) for val in first_row_df.iloc[0]] # a list of the expected types.

i = 1 # the current index. Start from 1 because we've already read the first row.
for row_df in reader:
    row_types = [type(val) for val in row_df.iloc[0]]
    if row_types != expected_types:
        print(i) # this row is the wanted one
        break
    i += 1

请注意,此代码假设第一行具有" true"类型。 这段代码非常慢,所以我建议你实际上只检查你认为有问题的列(虽然这不会带来很大的性能提升)。