簡體   English   中英

使用具有字符串第 n 個字符的條件的塊拆分非常大的 csv

[英]Splitting very large csv using chunks with conditions on the nth character of a string

我正在嘗試拆分一個非常大的(22GB)CSV 文件,同時使用數據中給定列的第 n 個字符的塊和條件。

我一直很無奈地嘗試將其結合起來: Python: Split CSV file 根據第一列的第一個字符

有這樣的東西,但我碰壁了。 我有一個列不是 null 的條件,但我想根據給定列的第 n 個字符拆分我的文件。

無論如何根據這種條件創建更小的 csv 文件。 任何幫助將不勝感激。

我的數據摘要如下所示:

源名稱 date_naissance date_deces date_mariage 地方
dgfkf47 YYYYMMDD YYYYMMDD 等等 等等
fhfidk67 YYYYMMDD YYYYMMDD 等等 等等
kgodj45 YYYYMMDD 等等 等等
paoror76 YYYYMMDD 萬維網 等等 等等
poldidj90 YYYYMMDD

我想要做的是創建一系列較小的文件,以便稍后通過根據列 ID 的第 7 個字符拆分數據來分析數據。 我知道如何在 5X10 中做到這一點,因為它適合我的 memory,我只是使用 groupby,但我被困在一個非常大的地方。 as ask 似乎並沒有讓我迭代 groupby。

我現在的策略是對 Dask 進行所有清理操作,包括創建一個僅包含第 7 個字符的新列,然后創建 output 較小的文件,這些文件可以加載到 pandas 中並按此列分組。

目前我已經做到了這一點,但我很想知道是否有一種簡單的方法可以做到這一點:

import dask.dataframe as dd
import glob, os
import pyarrow.parquet
import pyarrow as pa
from dask import multiprocessing
PATH = r"/RAW DATA/TEST/"
os.chdir(PATH)
for file in glob.glob("**/*_clean.csv", recursive=True):
    ddf = dd.read_csv(file, encoding='iso-8859-1', sep=';', dtype={'insee': 'object',
       'ref_document': 'object', 'ref_interne_sourcename': 'object',
       'sexe': 'object', 'profession': 'object', 'date_naissance': 'object', 'date_mariage': 'object', 'date_deces': 'object'})
# read to parquet
    ddf.to_parquet('file_clean.csv.parquet', engine='pyarrow', schema={'insee': pa.string(),
       'ref_document': pa.string(), 'ref_interne_sourcename': pa.string(),
       'sexe': pa.string(), 'profession': pa.string(), 'date_naissance': pa.string(), 'date_mariage': pa.string(), 'date_deces': pa.string()})
    ddf = dd.read_parquet('file_clean.csv.parquet', engine='pyarrow')
# split dates
    ddf['date_naissance']= dd.to_datetime(ddf['date_naissance'], format='%Y%m%d', errors='coerce')
    ddf['date_mariage']= dd.to_datetime(ddf['date_mariage'], format='%Y%m%d', errors='coerce')
    ddf['date_deces']= dd.to_datetime(ddf["date_deces"], format='%Y%m%d', errors='coerce')
    ddf['jour_naissance'] = ddf['date_naissance'].dt.day
    ddf['mois_mariage'] = ddf['date_naissance'].dt.month
    ddf['annee_mariage'] = ddf['date_naissance'].dt.year
    ddf['jour_mariage'] = ddf['date_mariage'].dt.day
    ddf['mois_mariage'] = ddf['date_mariage'].dt.month
    ddf['annee_mariage'] = ddf['date_mariage'].dt.year
    ddf['jour_deces'] = ddf['date_deces'].dt.day
    ddf['mois_deces'] = ddf['date_deces'].dt.month
    ddf['annee_deces'] = ddf['date_deces'].dt.year
# drop columns
    del ddf['date_naissance']
    del ddf['date_mariage']
    del ddf['date_deces']
# create IDTAG column
    ddf['IDTAG'] = ddf['sourcename'].str[6].fillna('')
    namefile = os.path.splitext(file)[0]
    ddf.to_csv(namefile)
    for partfile in glob.glob('**/*.part'):
        os.rename(partfile, (os.path.splitext(partfile)[0]) + "_{}_part.csv".format(namefile))
    for partfilecsv in glob.glob("**/*_part.csv", recursive=True):
        part_df = pd.read_csv(partfilecsv, encoding='iso-8859-1', sep=';')
# get a list of columns
        cols = list(part_df)
# move the column to head of list
        cols.insert(0, cols.pop(cols.index('IDTAG')))
# reorder
        part_df = part_df.loc[:, cols]
# group by IDTAG
        def firstletter(Index):
            firstentry = part_df.iloc[Index, 0]
            return firstentry[0]
        for letter, group in part_df.groupby(firstletter):
            group.to_csv((os.path.splitext(partfilecsv)[0]) + '_source_{}.csv'.format(letter))

好吧,這就是我設法做到的方式-然后是另一個腳本來合並生成的較小文件。 當然存在更優雅的解決方案。 快樂學習。

import dask.dataframe as dd
import glob, os
import pyarrow.parquet
import pyarrow as pa
from dask import multiprocessing
PATH = "path"
os.chdir(PATH)
for file in glob.glob("**/*_clean.csv", recursive=True):
    ddf = dd.read_csv(file, encoding='iso-8859-1', sep=';', dtype={'insee': 'object',
       'ref_document': 'object', 'ref_interne_sourcename': 'object',
       'sexe': 'object', 'profession': 'object', 'date_naissance': 'object', 'date_mariage': 'object', 'date_deces': 'object', 'lon': 'float'})
# read to parquet
    ddf.to_parquet('file_clean.csv.parquet', engine='pyarrow', schema={'insee': pa.string(),
       'ref_document': pa.string(), 'ref_interne_sourcename': pa.string(),
       'sexe': pa.string(), 'profession': pa.string(), 'date_naissance': pa.string(), 'date_mariage': pa.string(), 'date_deces': pa.string()})
    ddf = dd.read_parquet('file_clean.csv.parquet', engine='pyarrow', dtype={'insee': 'object',
       'ref_document': 'object', 'ref_interne_sourcename': 'object',
       'sexe': 'object', 'profession': 'object', 'date_naissance': 'object', 'date_mariage': 'object', 'date_deces': 'object', 'lon': 'float'})
# split dates
    ddf['date_naissance']= dd.to_datetime(ddf['date_naissance'], format='%Y%m%d', errors='coerce')
    ddf['date_mariage']= dd.to_datetime(ddf['date_mariage'], format='%Y%m%d', errors='coerce')
    ddf['date_deces']= dd.to_datetime(ddf["date_deces"], format='%Y%m%d', errors='coerce')
    ddf['jour_naissance'] = ddf['date_naissance'].dt.day
    ddf['mois_naissance'] = ddf['date_naissance'].dt.month
    ddf['annee_naissance'] = ddf['date_naissance'].dt.year
    ddf['jour_mariage'] = ddf['date_mariage'].dt.day
    ddf['mois_mariage'] = ddf['date_mariage'].dt.month
    ddf['annee_mariage'] = ddf['date_mariage'].dt.year
    ddf['jour_deces'] = ddf['date_deces'].dt.day
    ddf['mois_deces'] = ddf['date_deces'].dt.month
    ddf['annee_deces'] = ddf['date_deces'].dt.year
# drop columns
    del ddf['date_naissance']
    del ddf['date_mariage']
    del ddf['date_deces']
# create IDTAG column
    ddf['IDTAG'] = ddf['sourcename'].str[6].fillna('')
# save new part as csv
    namefile = os.path.splitext(file)[0]
    ddf.to_csv(namefile, index=False, encoding='iso-8859-1')
    for partfile in glob.glob('**/*.part'):
        os.rename(partfile, (os.path.splitext(partfile)[0]) + "_{}_part.csv".format(namefile))
# create dataframe for each part_csv file
for partfilecsv in glob.glob("**/*_part.csv", recursive=True):
    part_df = pd.read_csv(partfilecsv, encoding='iso-8859-1', dtype={'insee': 'object',
       'ref_document': 'object', 'ref_interne_sourcename': 'object',
       'sexe': 'object', 'profession': 'object', 'date_naissance': 'object', 'date_mariage': 'object', 'date_deces': 'object', 'lon': 'float', 'IDTAG': 'float'})
# get a list of columns
    cols = list(part_df)
# move the column to head of list
    cols.insert(0, cols.pop(cols.index('IDTAG')))
# reorder
    part_df = part_df.loc[:, cols]
# group by new column
    for idtag, group in part_df.groupby('IDTAG'):
        group.to_csv((os.path.splitext(partfilecsv)[0]) + '_source_{}.csv'.format(idtag), index=False)
# remove part_files
    os.remove(partfilecsv)```

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM