Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中按列的值拆分大csv文件_Python_Pandas - Fatal编程技术网

在python中按列的值拆分大csv文件

在python中按列的值拆分大csv文件,python,pandas,Python,Pandas,我有一个csv大文件,无法用python在内存中处理。在按照特定列的值进行分组后,我使用以下逻辑将其拆分为多个块: def splitDataFile(self, data_file): self.list_of_chunk_names = [] csv_reader = csv.reader(open(data_file, "rb"), delimiter="|") columns = csv_reader.next() for key,rows in gr

我有一个csv大文件,无法用python在内存中处理。在按照特定列的值进行分组后,我使用以下逻辑将其拆分为多个块:

def splitDataFile(self, data_file):

    self.list_of_chunk_names = []
    csv_reader = csv.reader(open(data_file, "rb"), delimiter="|")
    columns = csv_reader.next()

    for key,rows in groupby(csv_reader, lambda row: (row[1])):
        file_name = "data_chunk"+str(key)+".csv"
        self.list_of_chunk_names.append(file_name)

        with open(file_name, "w") as output:
            output.write("|".join(columns)+"\n")
            for row in rows:
                output.write("|".join(row)+"\n")

    print "message: list of chunks ", self.list_of_chunk_names

    return
逻辑在起作用,但速度很慢。我想知道如何优化这个?比如说熊猫

编辑


进一步解释:我不想简单地拆分为相同大小的块(比如每个块有1000行),我想按列的值拆分,这就是我使用groupby的原因

通过使用pandas的内置分块功能(从
chunksize
关键字arg到
read\u csv
),您可能会获得最佳性能

比如说,

reader = pd.read_table('my_data.csv', chunksize=4)
for chunk in reader:
  print(chunk)
编辑:

这可能会让你有所收获

import pandas as pd

group_col_indx = 1
group_col = pd.read_csv('test.csv', usecols=[group_col_indx])
keys = group_col.iloc[:,0].unique()

for key in keys:
    df_list = []
    reader = pd.read_csv('test.csv', chunksize=2)
    for chunk in reader:
        good_rows = chunk[chunk.iloc[:,group_col_indx] == key]
        df_list.append(good_rows)
    df_key = pd.concat(df_list)
使用此程序:

将其另存为
split csv.py
,并从资源管理器或命令运行它 线路

例如,根据第1列拆分
superuser.csv
,并写入
dstdir下的输出文件使用:

 python split-csv.py data.csv 1 dstdir
如果您在没有参数的情况下运行它,基于Tkinter的GUI将提示您 要选择输入文件,请选择列(基于1的索引)和 目标目录

我怀疑最大的瓶颈是每次处理新行块时打开和关闭文件句柄。一个更好的方法是,只要您写入的文件数量不太多,就保持所有文件都处于打开状态。这里有一个提纲:

def splitDataFile(self, data_file):
    open_files = dict()
    input_file = open(data_file, "rb")
    try:
        ...
        csv_reader = csv.reader(input_file, ...)
        ...
        for key, rows in groupby(csv_reader, lambda row: (row[1])):
            ...
            try:
                output = open_files[key]
            except KeyError:
                output = open(file_name, "w")
            output.write(...)
            ...
    finally:
        for open_file in open_files.itervalues():
            open_file.close()
        input_file.close()
当然,如果您只有一个组具有任何给定的密钥,这将没有帮助。(事实上,这可能会让事情变得更糟,因为你最终会不必要地打开一堆文件。)你越是频繁地向一个文件写入,你就越能从这一改变中获益


如果需要,您可以将其与pandas结合使用,并使用
read\u csv
read\u table
的分块功能来处理输入处理。

我将使用以下类似的方法,迭代要拆分的列的唯一值,以过滤数据分块

def splitWithPandas(data_file, split_by_column):
        values_to_split_by = pd.read_csv(data_file, delimiter="|", usecols=[split_by_column])
        values_to_split_by.drop_duplicates()
        values_to_split_by = pd.unique(values_to_split_by.values.ravel())

        for i in values_to_split_by:
            iter_csv = pd.read_csv(data_file, delimiter="|", chunksize=100000)
            df = pd.concat([chunk[chunk[split_by_column] == i] for chunk in iter_csv])
            df.to_csv("data_chunk_"+i, sep="|", index=False)

谢谢你的反馈。我不是在寻找简单的相同行数的分块。我正在寻找csv文件中给定列的值进行拆分。您可以对要分组的每个列值的块进行循环。是否可以在内存中设置要按其分组的单个列(这将允许您发现列中的唯一值)?是的,我可以在内存中设置要按其分组的单个列的大小。
def splitWithPandas(data_file, split_by_column):
        values_to_split_by = pd.read_csv(data_file, delimiter="|", usecols=[split_by_column])
        values_to_split_by.drop_duplicates()
        values_to_split_by = pd.unique(values_to_split_by.values.ravel())

        for i in values_to_split_by:
            iter_csv = pd.read_csv(data_file, delimiter="|", chunksize=100000)
            df = pd.concat([chunk[chunk[split_by_column] == i] for chunk in iter_csv])
            df.to_csv("data_chunk_"+i, sep="|", index=False)