পান্ডাসে একাধিক সিএসভি ফাইল আমদানি করুন এবং একটি ডেটা ফ্রেমে সংযুক্ত করে


403

আমি একটি ডিরেক্টরি থেকে পান্ডায় কয়েকটি সিএসভি ফাইল পড়তে এবং সেগুলিকে একটি বড় ডেটা ফ্রেমে যুক্ত করতে চাই like যদিও আমি তা বের করতে সক্ষম হইনি। আমার এখন পর্যন্ত যা আছে তা এখানে:

import glob
import pandas as pd

# get data file names
path =r'C:\DRO\DCL_rawdata_files'
filenames = glob.glob(path + "/*.csv")

dfs = []
for filename in filenames:
    dfs.append(pd.read_csv(filename))

# Concatenate all data into one DataFrame
big_frame = pd.concat(dfs, ignore_index=True)

আমার ধারণা লুপটির জন্য আমার কিছু সহায়তা দরকার ???


কারণ আপনি আপনার জন্য সংযোজন করা হয় না আপনার কোড কিছুই না dfsতালিকা, না তুমি লাইন প্রতিস্থাপন করতে চান data = pd.read_csv(filename)সঙ্গে dfs.append(pd.read_csv(filename)। এরপরে আপনাকে তালিকাটি লুপ করতে হবে এবং concat, আমি মনে করি না যে এর concatতালিকাতে কাজ করবে df
এডচুম

এছাড়াও আপনি আপনার শেষ লাইনে মডিউলের নামের সাথে একটি উপনাম মিশ্রণ করছেন, এটি হওয়া উচিত নয় big_frame = pd.concat(dfs, ignore_index=True), যাইহোক একবার আপনার ডাটাফ্রেমগুলির একটি তালিকা থাকলে আপনাকে তালিকাটির উপরে পুনরাবৃত্তি করতে হবে এবং এতে কনটাক্ট করতে হবেbig_frame
এডচুম

হ্যাঁ, আমি কোডটি সম্পাদনা করেছি, তবে আমি এখনও সিএসভি-ফাইলগুলি থেকে একযোগে ডেটাফ্রেম তৈরি করতে পারছি না, আমি অজগরে নতুন তাই আমার আরও কিছু সহায়তার দরকার আছে
জোনাস

আপনার dfsএখন লুপ করা দরকার , সুতরাং এর মতো কিছু for df in dfs: big_frame.concat(df, ignore_index=True)কাজ করা উচিত, আপনি চেষ্টা করার appendপরিবর্তেও চেষ্টা করতে concatপারেন।
এডচুম

আপনি কি বলতে পারেন ঠিক কি কাজ করছে না? কারণ concatআপনার মতো করে ঠিক সূক্ষ্মভাবে ডেটা ফ্রেমগুলির একটি তালিকা পরিচালনা করা উচিত। আমি মনে করি এটি একটি খুব ভাল পদ্ধতির।
জোরিস

উত্তর:


454

আপনার সমস্ত csvফাইলগুলিতে যদি একই কলাম থাকে তবে আপনি নীচের কোডটি চেষ্টা করতে পারেন। আমি যুক্ত করেছি header=0যাতে csvপ্রথম সারিটি পড়ার পরে কলামের নামগুলি অর্পণ করা যায়।

import pandas as pd
import glob

path = r'C:\DRO\DCL_rawdata_files' # use your path
all_files = glob.glob(path + "/*.csv")

li = []

for filename in all_files:
    df = pd.read_csv(filename, index_col=None, header=0)
    li.append(df)

frame = pd.concat(li, axis=0, ignore_index=True)

এটি মনে হচ্ছে কোনও পুরানো ফ্যাশনযুক্ত ওরফে ম্যানুয়াল পদ্ধতিগুলি করার মতো, esp। যেহেতু হ্যাপুড ইকোসিস্টেমটিতে এমন সরঞ্জামগুলির বর্ধমান তালিকা রয়েছে যেখানে আপনি বিভিন্ন ফাইল টাইপ (সিএসভি, জসন, টিএসটিএস, ডাটাবেস) সহ অনেকগুলি বিভিন্ন ডিরেক্টরিতে সরাসরি এসকিএল কোয়েরি সম্পাদন করতে পারেন যেন এটি একটি ডেটা উত্স। পাইথনের ক্ষেত্রেও একই রকম কিছু থাকতে হবে, যেহেতু এটি "বিগ ডেটা" করার জন্য ২০ বছরের লাফ শুরু করেছে।
হেক্সাটোনিক

275
একই জিনিসটি আরও সংক্ষিপ্ত, এবং সম্ভবত এটি তালিকা ব্যবহার না করায় দ্রুত: এটির পরিবর্তে df = pd.concat((pd.read_csv(f) for f in all_files)) একটিও সম্ভবত ব্যবহার os.path.join(path, "*.csv")করা উচিত path + "/*.csv"যা এটি ওএসকে স্বতন্ত্র করে তোলে।
সিড

4
এই উত্তরটি ব্যবহার করে আমাকে ফাইলের নাম সহ নতুন কলাম যুক্ত করতে দেওয়া হয়েছিল যেমন df['filename'] = os.path.basename(file_)ফাইল_ লুপের জন্য .. নিশ্চিত নয় সিডের উত্তর এটি অনুমতি দেয় কিনা?
20:48

4
@ কার্টিস্প আপনি সিডের উত্তর দিয়ে এখনও এটি করতে পারেন pandas.read_csv(f).assign(filename = foo), জেনারেটরের ভিতরে কেবল ব্যবহার করুন। assignনতুন কলামfilename
C8H10N4O2

আপনার যদি অনেকগুলি ফাইল থাকে তবে আমি সমস্ত জালিয়াতির আগে একটি তালিকাতে সংযোজন + আমদানির পরিবর্তে একটি জেনারেটর ব্যবহার করব।
গুস্তাফব্রস্টম

289

দারিন্ডো কোডারের উত্তরের বিকল্প :

path = r'C:\DRO\DCL_rawdata_files'                     # use your path
all_files = glob.glob(os.path.join(path, "*.csv"))     # advisable to use os.path.join as this makes concatenation OS independent

df_from_each_file = (pd.read_csv(f) for f in all_files)
concatenated_df   = pd.concat(df_from_each_file, ignore_index=True)
# doesn't create a list, nor does it append to one

2
@Sid @Mike চূড়ান্ত দুই লাইন দ্বারা প্রতিস্থাপিত করা যেতে পারে: pd.concat((pd.read_csv(f) for f in all_files), ignore_index=True)। ভিতরের বন্ধনীগুলি পান্ডাস সংস্করণ 0.18.1 দ্বারা প্রয়োজন
ইগোর ফোবিয়া

6
আমি glob.iglobপরিবর্তে ব্যবহার করার পরামর্শ দিই glob.glob; প্রথম এক রিটার্ন এবং পুনরুক্তিকারীর (পরিবর্তে একটি তালিকা)
টোটো_টিকো

54
import glob, os    
df = pd.concat(map(pd.read_csv, glob.glob(os.path.join('', "my_files*.csv"))))

4
দুর্দান্ত একটি লাইনার, বিশেষত দরকারী যদি কোনও পঠন_সিএসভি যুক্তি প্রয়োজন না হয়!
রাফেলওয়ালে

15
অন্যদিকে, যদি df = pd.concat(map(lambda file: pd.read_csv(file, delim_whitespace=True), data_files))
তর্কগুলি

functools.partial
ল্যাম্বডাস

34

ডাস্ক লাইব্রেরি একাধিক ফাইল থেকে একটি ডেটা ফ্রেম পড়তে পারে:

>>> import dask.dataframe as dd
>>> df = dd.read_csv('data*.csv')

(উত্স: http://dask.pydata.org/en/latest/example/dataframe-csv.html )

ডাস্ক ডেটাফ্রেমগুলি পান্ডাস ডেটাফ্রেম এপিআইয়ের একটি উপসেট বাস্তবায়ন করে। যদি সমস্ত ডেটা মেমরির সাথে ফিট করে তবে আপনি ডেটাফ্রেমকে পান্ডাস ডেটা ফ্রেমে রূপান্তর করতে কলdf.compute() করতে পারেন ।


30

এখানে প্রায় সমস্ত উত্তর হয় অকারণে জটিল (গ্লোব প্যাটার্ন মেলানো) বা অতিরিক্ত তৃতীয় পক্ষের লাইব্রেরিতে নির্ভর করে। পান্ডা এবং অজগর (সমস্ত সংস্করণ) ইতিমধ্যে অন্তর্নির্মিত সমস্ত কিছু ব্যবহার করে আপনি 2 লাইনে এটি করতে পারেন।

কয়েকটি ফাইলের জন্য - 1 লাইনার:

df = pd.concat(map(pd.read_csv, ['data/d1.csv', 'data/d2.csv','data/d3.csv']))

অনেক ফাইলের জন্য:

from os import listdir

filepaths = [f for f in listdir("./data") if f.endswith('.csv')]
df = pd.concat(map(pd.read_csv, filepaths))

এই পান্ডাস লাইন যা ডিএফ সেট করে 3 টি জিনিস ব্যবহার করে:

  1. পাইথনের মানচিত্র (ফাংশন, পুনরাবৃত্ত) ফাংশনে প্রেরণ করে (the pd.read_csv() ফাংশনটিতে (টি) পুনরাবৃত্তিযোগ্য (আমাদের তালিকা) যা ফাইলপথগুলির প্রতিটি সিএসভি উপাদান করে।
  2. পান্ডার রিড_সিএসভি () ফাংশন প্রতিটি সিএসভি ফাইলে স্বাভাবিক হিসাবে পড়ে।
  3. পান্ডার কনক্যাট () এগুলি একটি ডিএফ ভেরিয়েবলের আওতায় নিয়ে আসে।

3
বা সবেমাত্রdf = pd.concat(map(pd.read_csv, glob.glob('data/*.csv))
মিউন

আমি @ মুন দ্বারা নির্ধারিত পদ্ধতিটি চেষ্টা করেছিলাম। তবে, হেডারের সাথে আমার একাধিক ফাইল রয়েছে (শিরোনামগুলি সাধারণ)। আমি চাই না যে সেগুলি ডেটাফ্রেমে সংমিশ্রিত হোক। আপনি কি জানেন আমি কীভাবে এটি করতে পারি? আমি চেষ্টা করেছিলাম df = pd.concat(map(pd.read_csv(header=0), glob.glob('data/*.csv))কিন্তু এটিতে একটি ত্রুটি দিয়েছে "পার্সার_ফ () 1 টি প্রয়োজনীয় অবস্থানগত আর্গুমেন্ট:" ফাইলপথ_অর্থ_বফার "হারিয়েছে"
ক্যাডিপ

14

সম্পাদনা করুন: আমি https://stackoverflow.com/a/21232849/186078 এ আমার পথটি গুগলড করেছি । যাইহোক দেরিতে আমি নম্পি ব্যবহার করে যে কোনও ম্যানিপুলেশন করা এবং তারপরে পুনরাবৃত্তির ভিত্তিতে ডেটাফ্রেমটি নিজেই ম্যানিপুলেট করার চেয়ে একবার এটি ডেটাফ্রেমে অর্পণ করার জন্য এটি দ্রুত খুঁজে পাচ্ছি এবং এটিও এই সমাধানে কাজ করে বলে মনে হচ্ছে।

আমি এই পৃষ্ঠায় আঘাত করা যে কেউ এই পদ্ধতির বিষয়টি বিবেচনা করার জন্য আন্তরিকভাবে চাই, তবে এই বিশাল কোডের টুকরোটি কোনও মন্তব্য হিসাবে যুক্ত করে এটিকে কম পাঠ্যযোগ্য করে তুলতে চাই না।

আপনি ডেটা ফ্রেমের উপসংহারকে সত্যিকার অর্থে গতি বাড়ানোর জন্য অদৃশ্য লিভারেজ নিতে পারেন।

import os
import glob
import pandas as pd
import numpy as np

path = "my_dir_full_path"
allFiles = glob.glob(os.path.join(path,"*.csv"))


np_array_list = []
for file_ in allFiles:
    df = pd.read_csv(file_,index_col=None, header=0)
    np_array_list.append(df.as_matrix())

comb_np_array = np.vstack(np_array_list)
big_frame = pd.DataFrame(comb_np_array)

big_frame.columns = ["col1","col2"....]

সময় পরিসংখ্যান:

total files :192
avg lines per file :8492
--approach 1 without numpy -- 8.248656988143921 seconds ---
total records old :1630571
--approach 2 with numpy -- 2.289292573928833 seconds ---

"স্পিড আপ" ব্যাক করতে কোনও নম্বর? বিশেষতঃ, এটি স্ট্যাকওভারফ্লো / প্রশ্নগুলি /20906474/… এর চেয়ে দ্রুত ?
আইভান_পোজদেদেভ

আমি দেখতে পাচ্ছি না যে ওপি তার বক্তব্যকে ত্বরান্বিত করার জন্য কোনও উপায় চাইছে, এটি কেবল পূর্ব-বিদ্যমান গৃহীত উত্তরের পুনর্বারক বলে মনে হচ্ছে।
পাইডসাইনার

2
যদি ডেটা মিশ্র কলামের ধরণের থাকে তবে এটি কাজ করবে না।
পিমিন কনস্ট্যান্টিন কেফলালোকস

1
@ এসকেজি নিখুঁত .. এটি আমার পক্ষে একমাত্র কার্যকরী সমাধান। 500 টি ফাইল 400k সারি মোট 2 সেকেন্ডে। এটি পোস্ট করার জন্য ধন্যবাদ।
ফ্রাঙ্কসি

11

আপনি যদি পুনরাবৃত্তভাবে অনুসন্ধান করতে চান ( পাইথন 3.5 বা তার বেশি ) তবে আপনি নিম্নলিখিতটি করতে পারেন:

from glob import iglob
import pandas as pd

path = r'C:\user\your\path\**\*.csv'

all_rec = iglob(path, recursive=True)     
dataframes = (pd.read_csv(f) for f in all_rec)
big_dataframe = pd.concat(dataframes, ignore_index=True)

নোট করুন যে তিনটি শেষ লাইন একক লাইনে প্রকাশ করা যেতে পারে :

df = pd.concat((pd.read_csv(f) for f in iglob(path, recursive=True)), ignore_index=True)

আপনি ** এখানে ডকুমেন্টেশন খুঁজে পেতে পারেন । এছাড়াও, আমি iglobপরিবর্তে ব্যবহার করেছি glob, কারণ এটি তালিকার পরিবর্তে একটি পুনরাবৃত্তি প্রদান করে।



সম্পাদনা: মাল্টিপ্লাটফর্ম পুনরাবৃত্তি ফাংশন:

আপনি উপরের মাল্টিপ্লাটফর্ম ফাংশন (লিনাক্স, উইন্ডোজ, ম্যাক) এ গুটিয়ে রাখতে পারেন, তাই আপনি এটি করতে পারেন:

df = read_df_rec('C:\user\your\path', *.csv)

ফাংশনটি এখানে:

from glob import iglob
from os.path import join
import pandas as pd

def read_df_rec(path, fn_regex=r'*.csv'):
    return pd.concat((pd.read_csv(f) for f in iglob(
        join(path, '**', fn_regex), recursive=True)), ignore_index=True)

11

সহজ এবং দ্রুত

csvনামের তালিকা তৈরি না করেই দুই বা ততোধিকের আমদানি করুন ।

import glob

df = pd.concat(map(pd.read_csv, glob.glob('data/*.csv')))

8

একটি লাইনার ব্যবহার করছে mapতবে আপনি যদি অতিরিক্ত আরগগুলি নির্দিষ্ট করতে চান তবে আপনি এটি করতে পারেন:

import pandas as pd
import glob
import functools

df = pd.concat(map(functools.partial(pd.read_csv, sep='|', compression=None), 
                    glob.glob("data/*.csv")))

দ্রষ্টব্য: mapনিজেই আপনাকে অতিরিক্ত আরোগুলি সরবরাহ করতে দেয় না।


4

যদি একাধিক সিএসভি ফাইলগুলি জিপ করা থাকে তবে আপনি সমস্ত পড়তে এবং নীচের মত করে কনটেনেট করতে জিপফায়ার ব্যবহার করতে পারেন:

import zipfile
import numpy as np
import pandas as pd

ziptrain = zipfile.ZipFile('yourpath/yourfile.zip')

train=[]

for f in range(0,len(ziptrain.namelist())):
    if (f == 0):
        train = pd.read_csv(ziptrain.open(ziptrain.namelist()[f]))
    else:
        my_df = pd.read_csv(ziptrain.open(ziptrain.namelist()[f]))
        train = (pd.DataFrame(np.concatenate((train,my_df),axis=0), 
                          columns=list(my_df.columns.values)))

4

তালিকার বোধগম্যতার সাথে আরও একটি অন-লাইনার যা রিড_সিএসভি দিয়ে যুক্তিগুলি ব্যবহার করতে দেয়।

df = pd.concat([pd.read_csv(f'dir/{f}') for f in os.listdir('dir') if f.endswith('.csv')])

3

@ সিডের উত্তরের উত্তরের ভিত্তিতে।

যুক্তি দেওয়ার আগে, আপনি সিএসভি ফাইলগুলিকে একটি মধ্যবর্তী অভিধানে লোড করতে পারেন যা ফাইলের নামের (ফর্মের dict_of_df['filename.csv']) ভিত্তিতে প্রতিটি ডেটা সেটকে অ্যাক্সেস দেয় । উদাহরণস্বরূপ কলামের নামগুলি সারিবদ্ধ না করা হলে এই জাতীয় অভিধান আপনাকে ভিন্ন ভিন্ন ডেটা ফর্ম্যাটগুলির সমস্যাগুলি সনাক্ত করতে সহায়তা করতে পারে।

মডিউলগুলি আমদানি করুন এবং ফাইলের পথগুলি সনাক্ত করুন:

import os
import glob
import pandas
from collections import OrderedDict
path =r'C:\DRO\DCL_rawdata_files'
filenames = glob.glob(path + "/*.csv")

দ্রষ্টব্য: OrderedDictপ্রয়োজনীয় নয়, তবে এটি ফাইলগুলির ক্রমটি রাখবে যা বিশ্লেষণের জন্য কার্যকর হতে পারে।

অভিধানে সিএসভি ফাইল লোড করুন। তারপরে:

dict_of_df = OrderedDict((f, pandas.read_csv(f)) for f in filenames)
pandas.concat(dict_of_df, sort=True)

কীগুলি ফাইলের নাম fএবং মানগুলি হ'ল সিএসভি ফাইলগুলির ডেটা ফ্রেম সামগ্রী। fঅভিধান কী হিসাবে ব্যবহার করার পরিবর্তে , আপনি অভিধানের কীটির আকারটিকে প্রাসঙ্গিকভাবে কেবলমাত্র ছোট অংশে হ্রাস করার জন্য os.path.basename(f)বা অন্যান্য OS.path পদ্ধতি ব্যবহার করতে পারেন ।


3

pathlibলাইব্রেরি ব্যবহার করে বিকল্প (প্রায়শই পছন্দ করা হয় os.path)।

এই পদ্ধতিটি পান্ডা concat()/ এর পুনরাবৃত্তির ব্যবহার এড়িয়ে চলে apped()

পান্ডাস ডকুমেন্টেশন থেকে:
এটি লক্ষণীয় যে কনটাক্ট () (এবং তাই সংযোজন ()) ডেটার একটি সম্পূর্ণ অনুলিপি তৈরি করে এবং ক্রমাগত এই ফাংশনটি পুনরায় ব্যবহার করা একটি গুরুত্বপূর্ণ পারফরম্যান্স হিট তৈরি করতে পারে। আপনার যদি বেশ কয়েকটি ডেটাসেটের মাধ্যমে অপারেশনটি ব্যবহার করতে হয় তবে একটি তালিকা বোঝার ব্যবহার করুন।

import pandas as pd
from pathlib import Path

dir = Path("../relevant_directory")

df = (pd.read_csv(f) for f in dir.glob("*.csv"))
df = pd.concat(df)

-2

গুগল ড্রাইভে আপনি কোলাব ব্যবহার করে এটি করতে পারেন

import pandas as pd
import glob

path = r'/content/drive/My Drive/data/actual/comments_only' # use your path
all_files = glob.glob(path + "/*.csv")

li = []

for filename in all_files:
    df = pd.read_csv(filename, index_col=None, header=0)
    li.append(df)

frame = pd.concat(li, axis=0, ignore_index=True,sort=True)
frame.to_csv('/content/drive/onefile.csv')

-3
import pandas as pd
import glob

path = r'C:\DRO\DCL_rawdata_files' # use your path
file_path_list = glob.glob(path + "/*.csv")

file_iter = iter(file_path_list)

list_df_csv = []
list_df_csv.append(pd.read_csv(next(file_iter)))

for file in file_iter:
    lsit_df_csv.append(pd.read_csv(file, header=0))
df = pd.concat(lsit_df_csv, ignore_index=True)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.