بکندباز

خواندن و نوشتن فایل های CSV در پایتون

زیاد پیش می آید که اطلاعاتی دارید که می خواهید به برنامه های خود وارد و یا از آن خارج کنید، البته نه فقط از صفحه کلید و کنسول. تبادل اطلاعات از طریق فایل های متنی یک روش رایج برای اشتراک گذاری اطلاعات بین برنامه ها است. یکی از محبوب ترین فرمت ها برای تبادل داده، فرمت CSV است. اما چگونه از آن استفاده می کنید؟

بیایید یک چیز را روشن کنیم: شما مجبور نیستید (و نخواهید شد) که کد تجزیه کننده CSV خود را از ابتدا بسازید. چندین کتابخانه کاملاً قابل قبول از قبل وجود دارد که می توانید از آنها استفاده کنید. کتابخانه داخلی csv در پایتون برای اکثر موارد مربوط به تجزیه فایل csv کار خواهد کرد. اگر هم کار شما داده های زیادی دارد و یا تجزیه و تحلیل عددی نیاز دارد، کتابخانه pandas که دارای قابلیت تجزیه CSV نیز هست، برای مدیریت این موارد کافی است.

در این مقاله، نحوه خواندن، پردازش و تجزیه CSV از فایل های متنی را با استفاده از پایتون خواهید آموخت. خواهید دید که فایل‌های CSV چگونه کار می‌کنند، در مورد csv، کتابخانه بسیار مهم تعبیه‌شده در پایتون را یاد می‌گیرید و خواهید دید که تجزیه CSV با استفاده از کتابخانه pandas چگونه کار می‌کند .

پس بیایید شروع کنیم!

فایل CSV چیست؟

فایل CSV (فایل مقادیر جدا شده با کاما) نوعی فایل متنی ساده است که از ساختار خاصی برای مرتب کردن داده های جدولی استفاده می کند. از آنجایی که یک فایل متنی ساده است، فقط می‌تواند حاوی داده‌های متنی واقعی باشد – به عبارت دیگر، کاراکترهای ASCII و یا Unicode قابل چاپ .

ساختار یک فایل CSV با نام آن مشخص شده است. به طور معمول، فایل‌های CSV از یک کاما برای جدا کردن هر مقدار داده خاص استفاده می‌کنند. این ساختار به شکل زیر است:

column 1 name,column 2 name, column 3 name
first row data 1,first row data 2,first row data 3
second row data 1,second row data 2,second row data 3
...

توجه کنید که چگونه هر قطعه داده با کاما از هم جدا می شود. به طور معمول، خط اول فایل، عنوانِ هر بخش از داده را مشخص می کند – به عبارت دیگر، نام ستون داده را. هر خط بعدی پس از آن داده واقعی است که فقط با محدودیت اندازه فایل محدود می شود.

به طور کلی کاراکتر جداکننده، “جداکننده یا delimiter” نامیده می شود و کاما تنها علامت مورد استفاده نیست. دیگر جداکننده های محبوب عبارتند از تب ( \t)، کولون ( :) و نیم دونقطه ( ;). تجزیه صحیح یک فایل CSV مستلزم آن است که بدانیم از کدام جداکننده استفاده می شود.

فایل های CSV از کجا می آیند؟

فایل‌های CSV معمولاً توسط برنامه‌هایی ایجاد می‌شوند که حجم زیادی از داده را مدیریت می‌کنند. csv ها یک راه راحت برای اکسپورت داده ها از فایل های اکسل یا پایگاه داده و همچنین ایمپورت کردن یا استفاده از آن در برنامه های دیگر هستند. به عنوان مثال، ممکن است نتایج یک برنامه داده کاوی را به یک فایل CSV صادر کنید و سپس آن را به اکسل وارد کنید تا داده ها را تجزیه و تحلیل کنید، نمودارهایی را برای ارائه ایجاد کنید، یا گزارشی را برای انتشار آماده کنید.

کار با فایل های CSV به صورت برنامه نویسی بسیار آسان است. هر زبانی که از ورودی فایل متنی و دستکاری رشته ها پشتیبانی می کند (مانند پایتون) می تواند مستقیماً با فایل های CSV کار کند.

تجزیه فایل‌های CSV با کتابخانه CSV داخلی پایتون

این کتابخانه عملکردی را برای خواندن و نوشتن در فایل‌های CSV فراهم می‌کند. برای کار کردن با فایل های CSV تولید شده توسط Excel طراحی شده است، اما به راحتی برای کار با انواع فرمت های CSV سازگار است. این کتابخانه حاوی اشیاء و کدهایی برای خواندن، نوشتن و پردازش داده ها از فایل های CSV است.

خواندن فایل های CSV با کتابخانه csv

خواندن از یک فایل CSV با استفاده از شی reader انجام می شود. فایل CSV به عنوان یک فایل متنی با تابع داخلی پایتون به نام open() باز می شود که یک شی فایل را برمی گرداند. سپس برای پردازش به متد reader منتقل می شود.

این محتوای فایل employee_birthday.csv است:

name,department,birthday month
John Smith,Accounting,November
Erica Meyers,IT,March

و این کدی برای خواندن آن است:

import csv

with open('employee_birthday.csv') as csv_file:
    csv_reader = csv.reader(csv_file, delimiter=',')
    line_count = 0
    for row in csv_reader:
        if line_count == 0:
            print(f'Column names are {", ".join(row)}')
            line_count += 1
        else:
            print(f'\t{row[0]} works in the {row[1]} department, and was born in {row[2]}.')
            line_count += 1
    print(f'Processed {line_count} lines.')

این کد منجر به خروجی زیر می شود:

Column names are name, department, birthday month
    John Smith works in the Accounting department, and was born in November.
    Erica Meyers works in the IT department, and was born in March.
Processed 3 lines.

هر ردیفی که توسطreader برگردانده می‌شود، فهرستی از عناصر String حاوی داده‌هایی است که با حذف جداکننده‌ها پیدا شده‌اند. سطر اول برگشتی حاوی نام ستون ها است که به روش خاصی مدیریت می شود.

خواندن فایل‌های CSV در دیکشنری با کتابخانه csv

به جای خواندن اطلاعات فایل به صورت لیستی از عناصر String، می‌توانید داده‌های CSV را مستقیماً در یک دیکشنری نیز بخوانید.

باز هم فایل ورودی ما employee_birthday.csvصورت زیر است:

name,department,birthday month
John Smith,Accounting,November
Erica Meyers,IT,March

در اینجا کدی برای خوندن فایل ها به صورت دیکشنری داریم:

import csv

with open('employee_birthday.txt', mode='r') as csv_file:
    csv_reader = csv.DictReader(csv_file)
    line_count = 0
    for row in csv_reader:
        if line_count == 0:
            print(f'Column names are {", ".join(row)}')
            line_count += 1
        print(f'\t{row["name"]} works in the {row["department"]} department, and was born in {row["birthday month"]}.')
        line_count += 1
    print(f'Processed {line_count} lines.')

و نتیجه همان خروجی قبلی است:

Column names are name, department, birthday month
    John Smith works in the Accounting department, and was born in November.
    Erica Meyers works in the IT department, and was born in March.
Processed 3 lines.

کلیدهای دیکشنری از کجا آمده اند؟ همیشه فرض بر این است که خط اول فایل CSV حاوی کلیدهایی است که برای ساخت دیکشنری استفاده می شود. اگر اینها را در فایل CSV خود ندارید، باید کلیدهای خود را با تنظیم پارامتر اختیاری fieldnames با لیستی که حاوی این کلید هاست، مشخص کنید.

پارامترهای اختیاری متد reader در کتابخانه CSV پایتون

شی readerمی‌تواند با تعیین پارامترهای اضافی ، سبک‌های مختلفی از فایل‌های CSV را مدیریت کند که برخی از آنها در زیر نشان داده شده‌اند:

  • delimiter: کاراکتر مورد استفاده برای جداسازی هر فیلد را مشخص می کند. پیش فرض کاما ( ',') است.
  • quotechar: کاراکتر مورد استفاده برای فیلدهای اطراف که حاوی کاراکتر جداکننده هستند را مشخص می کند. پیش فرض دابل کوتیشن ( ' " ') است.
  • escapechar: کاراکتر مورد استفاده برای escape کاراکتر جداکننده را مشخص می کند، در صورتی که از کوتیشن برای متن ها استفاده نشود. پیش فرض کاراکتر بدون escape است.

این پارامترها شایسته توضیح بیشتری هستند. فرض کنید با employee_addresses.csv فایل زیر کار می کنید:

name,address,date joined
john smith,1132 Anywhere Lane Hoboken NJ, 07030,Jan 4
erica meyers,1234 Smith Lane Hoboken NJ, 07030,March 2

این فایل CSV شامل سه فیلد است: nameaddressو date joined, که با کاما از هم جدا می شوند. مشکل این است که داده های فیلد address نیز خود حاوی یک کاما برای نشان دادن کد پستی است.

سه راه مختلف برای مدیریت این وضعیت وجود دارد:

  • از یک جداکننده متفاوت استفاده کنید
    به این ترتیب، کاما را می توان با خیال راحت در خود داده استفاده کرد. شما از پارامتر اختیاری delimiter برای تعیین یک جداکننده جدید به جز کاما استفاده می کنید.
  • داده ها را در کوتیشن قرار دهید
    با این کار، ماهیت خاص جداکننده انتخابی شما در رشته های درون کوتیشن نادیده گرفته می شود. بنابراین، می توانید کاراکتر مورد استفاده برای کوتیشن را با پارامتر اختیاری quotechar مشخص کنید. تا زمانی که آن کاراکتر نیز در داده ها ظاهر نشود، همه چیز خوب پیش می رود.
  • Escape کاراکترهای جداکننده در داده ها
    کاراکترهای Escape درست مانند رشته های فرمت کار می کنند و تفسیر کاراکتر Escape شده (در این مورد، جداکننده) را باطل می کنند. اگر از یک کاراکتر Escape استفاده می شود، باید با استفاده از پارامتر اختیاری escapechar مشخص شود.

نوشتن در فایل های CSV با استفاده از کتابخانه CSV پایتون

شما همچنین می توانید با استفاده از یک writerشی و .write_row()روش در یک فایل CSV بنویسید:

import csv

with open('employee_file.csv', mode='w') as employee_file:
    employee_writer = csv.writer(employee_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)

    employee_writer.writerow(['John Smith', 'Accounting', 'November'])
    employee_writer.writerow(['Erica Meyers', 'IT', 'March'])

پارامتر quotecharاختیاری به آن می گوید writerکه هنگام نوشتن از کدام کاراکتر برای نقل قول فیلدها استفاده شود. با این حال، اینکه آیا نقل قول استفاده می شود یا نه، توسط quotingپارامتر اختیاری تعیین می شود:

  • اگر quotingروی تنظیم شده باشد csv.QUOTE_MINIMAL، .writerow()فیلدها را فقط در صورتی نقل قول می کند که حاوی delimiterیا quotecharباشند. این مورد پیش فرض است.
  • اگر quotingروی تنظیم شده باشد csv.QUOTE_ALL، .writerow()تمام فیلدها نقل قول خواهد شد.
  • اگر quotingروی تنظیم شده باشد csv.QUOTE_NONNUMERIC، .writerow()تمام فیلدهای حاوی داده های متنی را نقل قول می کند و همه فیلدهای عددی را به floatنوع داده تبدیل می کند.
  • اگر quotingروی تنظیم شده است csv.QUOTE_NONE، .writerow()به جای نقل قول از جداکننده ها فرار می کند. در این مورد، شما همچنین باید یک مقدار برای escapecharپارامتر اختیاری ارائه دهید.

خواندن مجدد فایل به صورت متن ساده نشان می دهد که فایل به صورت زیر ساخته شده است:

John Smith,Accounting,November
Erica Meyers,IT,March

نوشتن فایل CSV از دیکشنری باcsv

از آنجایی که می‌توانید داده‌های ما را در فرهنگ لغت بخوانید، عادلانه است که بتوانید آن‌ها را از یک فرهنگ لغت نیز بنویسید:

import csv

with open('employee_file2.csv', mode='w') as csv_file:
    fieldnames = ['emp_name', 'dept', 'birth_month']
    writer = csv.DictWriter(csv_file, fieldnames=fieldnames)

    writer.writeheader()
    writer.writerow({'emp_name': 'John Smith', 'dept': 'Accounting', 'birth_month': 'November'})
    writer.writerow({'emp_name': 'Erica Meyers', 'dept': 'IT', 'birth_month': 'March'})

بر خلاف DictReaderfieldnamesپارامتر هنگام نوشتن فرهنگ لغت مورد نیاز است. وقتی به آن فکر می‌کنید، این منطقی است: بدون فهرستی از fieldnames، DictWriterنمی‌دانید از کدام کلیدها برای بازیابی مقادیر از فرهنگ‌های لغت خود استفاده کنید. همچنین از کلیدهای ورودی fieldnamesبرای نوشتن ردیف اول به عنوان نام ستون استفاده می کند.

کد بالا فایل خروجی زیر را تولید می کند:

emp_name,dept,birth_month
John Smith,Accounting,November
Erica Meyers,IT,March

تجزیه فایل‌های CSV با کتابخانه pandas

خواندن فایل های CSV با pandas نیز امکان پذیر است . اگر داده های زیادی برای تجزیه و تحلیل دارید، استفاده از pandas به شدت توصیه می شود.

pandas یک کتابخانه منبع باز پایتون است که ابزارهای تجزیه و تحلیل داده با کارایی بالا و ساختارهای داده با استفاده آسان را ارائه می دهد. pandas برای همه ورژن‌های پایتون در دسترس است.

نصب pandasو وابستگی های آن در Anacondaراحتی انجام می شود:

$ conda install pandas

همانطور که از pip/pipenv برای سایر نصب های پایتون استفاده می شود:

$ pip install pandas

در اینجا به جزئیات نحوه عملکرد pandas یا نحوه استفاده از آن نخواهیم پرداخت و فقط بخشی از قابلیت های این کتابخانه را برای مدیریت فایل های csv بررسی می کنیم.

خواندن فایل های CSV باpandas

برای نشان دادن برخی از قدرت‌های pandas در مدیریت فایل های CSV، یک فایل کمی پیچیده‌تر برای خواندن ایجاد کرده‌ام به نام hrdata.csv. این فایل شامل داده هایی در مورد کارکنان شرکت است:

Name,Hire Date,Salary,Sick Days remaining
Graham Chapman,03/15/14,50000.00,10
John Cleese,06/01/15,65000.00,8
Eric Idle,05/12/14,45000.00,10
Terry Jones,11/01/13,70000.00,3
Terry Gilliam,08/12/14,48000.00,7
Michael Palin,05/23/13,66000.00,8

خواندن CSV به شکل داده DataFrame در pandas سریع و ساده است:

import pandas
df = pandas.read_csv('hrdata.csv')
print(df)

همین: سه خط کد، و البته تنها یکی از این خط ها کار اصلی را انجام می دهد. pandas.read_csv()فایل CSV داده شده را باز می کند، تجزیه و تحلیل می کند، می خواند و داده ها را در DataFrame ذخیره می کند.

چاپ نتایج خروجی در قالب DataFrame:

             Name Hire Date   Salary  Sick Days remaining
0  Graham Chapman  03/15/14  50000.0                   10
1     John Cleese  06/01/15  65000.0                    8
2       Eric Idle  05/12/14  45000.0                   10
3     Terry Jones  11/01/13  70000.0                    3
4   Terry Gilliam  08/12/14  48000.0                    7
5   Michael Palin  05/23/13  66000.0                    8

در اینجا چند نکته قابل ذکر است:

  • ابتدا pandasمتوجه شد که خط اول CSV حاوی نام ستون است و به طور خودکار از آنها استفاده کرد. که عملکرد خیلی خوبی است.
  • با این حال، pandasاز ایندکس های عدد صحیح شروع شده از صفر در DataFrame استفاده می کند. این به این دلیل است که ما به آن نگفتیم که ایندکس ما چقدر باید باشد.
  • علاوه بر این، اگر به انواع داده‌های ستون‌های ما نگاه کنید، خواهید دید که ستون‌های  Salary و Sick Days remaining  به درستی به اعداد تبدیل شده است، اما ستون Hire Date همچنان یک string است. همانطور که در حالت تعاملی دیده می شود:
  • >>> print(type(df['Hire Date'][0]))
    <class 'str'>
    

بیایید یکی یکی به این مسائل بپردازیم. برای استفاده از ستون دیگری به عنوان ایندکس DataFrame،  پارامتر اختیاری index_colرا اضافه کنید:

import pandas
df = pandas.read_csv('hrdata.csv', index_col='Name')
print(df)

اکنون فیلد Name ایندکس DataFrame ما است:

               Hire Date   Salary  Sick Days remaining
Name                                                  
Graham Chapman  03/15/14  50000.0                   10
John Cleese     06/01/15  65000.0                    8
Eric Idle       05/12/14  45000.0                   10
Terry Jones     11/01/13  70000.0                    3
Terry Gilliam   08/12/14  48000.0                    7
Michael Palin   05/23/13  66000.0                    8

بعد، بیایید نوع داده فیلد Hire Date را اصلاح کنیم. می‌توانید با پارامتر اختیاری parse_dates، که به‌عنوان فهرستی از نام ستون‌ها به‌عنوان تاریخ در نظر گرفته می‌شود،  pandasرا مجبور به خواندن داده‌ها به‌عنوان یک تاریخ کینم:

import pandas
df = pandas.read_csv('hrdata.csv', index_col='Name', parse_dates=['Hire Date'])
print(df)

به تفاوت در خروجی توجه کنید:

                Hire Date   Salary  Sick Days remaining
Name                                                   
Graham Chapman 2014-03-15  50000.0                   10
John Cleese    2015-06-01  65000.0                    8
Eric Idle      2014-05-12  45000.0                   10
Terry Jones    2013-11-01  70000.0                    3
Terry Gilliam  2014-08-12  48000.0                    7
Michael Palin  2013-05-23  66000.0                    8

اکنون تاریخ به درستی قالب بندی شده است که به راحتی در ترمینال تعاملی دیده می شود:

>>>

>>> print(type(df['Hire Date'][0]))
<class 'pandas._libs.tslibs.timestamps.Timestamp'>

اگر فایل‌های CSV شما در خط اول نام ستون‌ها را ندارند، می‌توانید از پارامتر اختیاری names برای ارائه فهرستی از نام ستون‌ها استفاده کنید. همچنین اگر می خواهید نام ستون های ارائه شده در خط اول را دوباره نویسی کنید نیز، می توانید از این استفاده کنید. در این مورد، باید با استفاده از پارامتر اختیاری header=0  نیز به pandas.read_csv() بگویید که نام ستون های پیشفرض را نادیده بگیرد:

import pandas
df = pandas.read_csv('hrdata.csv', 
            index_col='Employee', 
            parse_dates=['Hired'], 
            header=0, 
            names=['Employee', 'Hired','Salary', 'Sick Days'])
print(df)

توجه داشته باشید که از آنجایی که نام ستون ها تغییر کرده است، ستون های مشخص شده در پارامترهای اختیاری index_col و parse_dates نیز باید تغییر کنند. اکنون خروجی زیر حاصل می شود:

                    Hired   Salary  Sick Days
Employee                                     
Graham Chapman 2014-03-15  50000.0         10
John Cleese    2015-06-01  65000.0          8
Eric Idle      2014-05-12  45000.0         10
Terry Jones    2013-11-01  70000.0          3
Terry Gilliam  2014-08-12  48000.0          7
Michael Palin  2013-05-23  66000.0          8

نوشتن در فایل های CSV با pandas

نوشتن یک  DataFrameدر یک فایل CSV به آسانی خواندن آن است. بیایید داده ها را با نام ستون های جدید در یک فایل CSV جدید بنویسیم:

import pandas
df = pandas.read_csv('hrdata.csv', 
            index_col='Employee', 
            parse_dates=['Hired'],
            header=0, 
            names=['Employee', 'Hired', 'Salary', 'Sick Days'])
df.to_csv('hrdata_modified.csv')

تنها تفاوت این کد با کد خواندن قبل این است که تابع print(df) با df.to_csv() جایگزین شده است و نام فایل نیز به عنوان ورودی به این تابع ارسال شده است. فایل CSV جدید به شکل زیر است:

Employee,Hired,Salary,Sick Days
Graham Chapman,2014-03-15,50000.0,10
John Cleese,2015-06-01,65000.0,8
Eric Idle,2014-05-12,45000.0,10
Terry Jones,2013-11-01,70000.0,3
Terry Gilliam,2014-08-12,48000.0,7
Michael Palin,2013-05-23,66000.0,8

نتیجه

اگر اصول اولیه خواندن فایل‌های CSV را بدانید، وقتی نیاز به وارد کردن داده‌ها دارید، هرگز دچار سردرگمی نخواهید شد. اکثر کارهای خواندن، پردازش و نوشتن CSV را می توان به راحتی توسط کتابخانه اصلی csv پایتون انجام داد. اگر داده‌های زیادی برای خواندن و پردازش دارید، کتابخانه pandas قابلیت‌های مدیریت سریع و آسان CSV را نیز فراهم می‌کند.

backendbaz

مدیر وب سایت بکندباز

دیدگاه‌ها

*
*