ربما سبق لك أن رأيت البيانات الجدولية من قبل: فهي ببساطة عبارة عن صفوف وأعمدة تحتوي على بعض البيانات. (فكر في جدول في مقال أو جدول بيانات Excel.) تعد ملفات CSV واحدة من أكثر أنواع الجداول شيوعًا التي يستخدمها علماء البيانات، ولكنها قد تكون شاقة إذا كنت لا تعرف بالضبط كيفية عملها أو كيفية استخدامها جنبًا إلى جنب مع بايثون.
في هذه المقالة، سنتعرف على ملفات CSV وكيفية استخدام بايثون للعمل معها. سنبدأ بتعلم ماهية ملفات CSV بالفعل. بعد ذلك، سنتعلم كيفية استخدام وحدة csv المدمجة في بايثون لقراءة ملفات CSV وكتابتها بسرعة وفعالية.
بنية ملف CSV
باختصار، ملف CSV هو ملف نص عادي يمثل جدولاً. يتم تخزين البيانات على هيئة صفوف وأعمدة. يشير اسم CSV إلى القيم المنفصلة بفاصلة، مما يعني أن أعمدة الجدول مفصولة بفاصلة. من ناحية أخرى، يتم فصل الصفوف ببساطة بخطوط في الملف. غالبًا ما يكون السطر الأول هو رأس الجدول، والذي يحتوي على وصف للبيانات في كل عمود.
دعنا نعمل على ملف CSV كمثال باسم people.csv. هذا هو شكله إذا فتحناه باستخدام محرر نصوص:
كما ترى، يتم تعريف الأعمدة بفواصل. يخزن العمود الأول (تحت تسمية العنوان name
وقبل الفاصلة الأولى في كل سطر) اسم كل شخص. بعد الفاصلة الأولى يأتي العمود id
، ثم age
، وهكذا. يمكن استخدام رموز الاقتباس لتغليف النص، كما هو موضح في عمود id
.
نظرًا لأن الفواصل لا تتطابق بالضرورة، فمن الصعب بعض الشيء تصور كل عمود في نص عادي. من الأسهل فهم البيانات الموجودة داخل ملف CSV إذا فتحناه في جدول بيانات مثل Excel أو Google Sheets أو LibreOffice Calc:
هذا أفضل بكثير! لاحظ أيضًا كيف تم تفسير القيم في عمود id
كنص. إذا لم تكن محاطة بعلامات اقتباس، فسيتم اعتبارها أرقامًا وسيتم تجاهل الأصفار الأولية عند تحميل البيانات.
قد يؤدي فتح ملفات CSV كجداول بيانات إلى نتائج غير متوقعة – على سبيل المثال، قد يعتقد البرنامج أن الفواصل هي فواصل رقمية بدلاً من فواصل الأعمدة. تتضمن بعض برامج جداول البيانات (مثل Excel) وظيفة استيراد CSV التي تتيح لك تحديد فواصل الأعمدة وأنواع البيانات، من بين معلمات أخرى. راقب للتأكد من عدم تعديل بياناتك عن غير قصد!
استخدام بايثون لقراءة ملف CSV
حسنًا، لدينا فكرة أساسية عن ماهو ملف CSV. ولكن كيف يمكنك فتحه باستخدام بايثون؟
قد تميل إلى استخدام الدالة open()
لقراءة محتويات الملف، وتقسيم السطر عند كل فاصل عمود، وأخيرًا وضعه في بنية بيانات مثل القائمة أو القاموس. (ملاحظة جانبية: إذا لم تسمع عن الدالة open()
، فنوصيك بقراءة مقالتنا حول كيفية الكتابة إلى ملف في بايثون.)
ملفات CSV منتشرة على نطاق واسع لدرجة أن فريق تطوير بايثون قام بإنشاء وحدة CSV. نحتاج فقط إلى استيراد هذه الوحدة وسنتمكن من الوصول إلى العديد من الدوال المتعلقة بتحميل البيانات من ملفات CSV وكتابتها مرة أخرى فيها.
الدالة الأساسية لقراءة ملف CSV هي csv.reader
. يمكننا استخدامها بفتح ملف CSV (باستخدام الدالة open()
)، ثم تمرير معرّف الملف الذي تم إنشاؤه بواسطة الدالة open()
إلى الدالة csv.reader
. يمكنك رؤية شكل الكود أدناه. (نفترض أنك تقوم بتنفيذ بايثون في نفس المجلد الذي يوجد به ملف people.csv
.)
import csv
with open('people.csv') as csv_file:
reader = csv.reader(csv_file)
for row in reader:
print(row)
# output:
# ['name', 'id', 'age', 'department', 'likes_pizza']
# ['James', '001', '22', 'sales', 'True']
# ['John', '002', '28', 'engineering', 'False']
# ['Jessica', '003', '25', 'engineering', 'True']
# ['Monica', '004', '29', 'accounting', 'False']
كما ترى، يقوم القارئ تلقائيًا بتنظيم البيانات في صفوف. وعندما نكرر عملية القراءة على القارئ، ينتهي بنا الأمر إلى تكرار عملية القراءة على الصفوف في ملف CSV. يتم تخزين هذه الصفوف كقوائم، دون الحاجة إلى إنشاء قائمة بأنفسنا.
تقبل دالة csv.reader
العديد من الوسائط المختلفة لتحليل معايير التنسيق المختلفة في ملف CSV. على سبيل المثال، على الرغم من وجود “comma-separated” في اسمها، تستخدم بعض ملفات CSV أحرفًا أخرى لتحديد الأعمدة أو حتى لاقتباس النص. إذا صادفت مثل هذه الحالة، فيمكنك تحديد هذه الأحرف باستخدام الكلمات المفتاحية delimiter
وquotechar
على التوالي:
import csv
with open('people.csv') as csv_file:
reader = csv.reader(csv_file, delimiter=';', quotechar='!')
for row in reader:
print(row)
# output:
# ['name,id,age,department,likes_pizza']
# ['James,"001",22,sales,True']
# ['John,"002",28,engineering,False']
# ['Jessica,"003",25,engineering,True']
# ['Monica,"004",29,accounting,False']
في هذه الحالة، و نظرًا لأننا استخدمنا delimiter
غير صحيح وquotechar
غير صحيح للتنسيق في ملف people.csv، فقد انتهينا إلى صفوف مقسمة بشكل سيئ في reader
. كان ينبغي لنا استخدام الإعدادات الافتراضية فقط!
على أي حال، فإن معرفة كيفية تغيير هذه المعلمات مفيدة إذا صادفت ملف CSV بتنسيق مختلف. على سبيل المثال، غالبًا ما سترى الفاصلة المنقوطة ( ؛
) تُستخدم كفاصل للأعمدة في ملفات CSV التي نشأت في بلدان تستخدم فيها الفاصلة ( ،
) للقيم العشرية.
قراءة ملف CSV كقاموس باستخدام بايثون
كانت أمثلتنا في القسم الأخير تعاني من مشكلة واضحة: حيث يظهر صف الرأس بجوار الصفوف التي تحتوي على قيم! ومن الناحية المثالية، ونظرًا لأن الرأس والقيم لهما معاني مختلفة في الجدول، فإننا نريد أيضًا التعامل معهما بشكل مختلف.
لحسن الحظ، لدينا كائن csv.DictReader
في خدمتنا. وهو يعمل مثل كائن csv.reader
العادي من قبل (يمكنك حتى تمرير نفس الوسائط، مثل delimiter
وquotechar
)، ولكنه يتألف من قواميس، بدلاً من القوائم. علاوة على ذلك، تأتي مفاتيح القاموس من رأس ملف CSV!
هكذا يبدو الأمر أثناء العمل:
import csv
with open('people.csv') as csv_file:
reader = csv.DictReader(csv_file)
for row in reader:
print(row)
# output:
# {'name': 'James', 'id': '001', 'age': '22', 'department': 'sales', 'likes_pizza': 'True'}
# {'name': 'John', 'id': '002', 'age': '28', 'department': 'engineering', 'likes_pizza': 'False'}
# {'name': 'Jessica', 'id': '003', 'age': '25', 'department': 'engineering', 'likes_pizza': 'True'}
# {'name': 'Monica', 'id': '004', 'age': '29', 'department': 'accounting', 'likes_pizza': 'False'}
انظر كيف أصبحت تسميات الرأس هي مفاتيح قاموس كل صف؟ يفترض csv.DictReader
أن الصف الأول هو الرأس – وهو افتراض آمن للغاية – ويستخدم تسمياته لإنشاء القواميس. بطبيعة الحال، هذا يعني أن صف الرأس لا يظهر عند التكرار عبر csv.DictReader
.
في البداية، قد لا يبدو csv.DictReader
بمثابة خطوة كبيرة من csv.reader
. ومع ذلك، فإن استخدام القواميس ذات العلامات الرأسية يسمح لنا بالعمل مع القيم بشكل أنظف. يسرد الكود التالي اسم وعمر كل شخص – آمل أن تتفق معي على مدى وضوح الكود وسهولة فهمه:
import csv
with open('people.csv') as csv_file:
reader = csv.DictReader(csv_file)
for row in reader:
name = row['name']
age = row['age']
print(name, 'is', age, 'years old.')
# output:
# James is 22 years old.
# John is 28 years old.
# Jessica is 25 years old.
# Monica is 29 years old.
استخدام بايثون لكتابة ملف CSV
ماذا عن كتابة البيانات إلى ملف CSV؟ حسنًا، تتضمن وحدة csv دالة csv.writer
لهذا الغرض؛ وهي تعمل مثل csv.read
. ومع ذلك، دعنا ننتقل إلى الأمام ونلقي نظرة على csv.DictWriter
الأكثر قوة. دعنا نستخدمها لإنشاء ملف جديد تمامًا يسمى names.csv:
import csv
with open('names.csv', 'w') as csv_file:
header = ['first', 'last']
writer = csv.DictWriter(csv_file, fieldnames=header)
writer.writeheader()
writer.writerow({'first': 'Jack', 'last': 'Hill'})
writer.writerow({'first': 'James', 'last': 'Mitch'})
هناك الكثير مما يحدث، لذا دعونا نأخذ الأمر خطوة بخطوة:
- نبدأ بفتح ملف في وضع الكتابة (
'w'
)، مما سيؤدي إلى إنشاء ملف CSV جديد تمامًا في نظام الملفات الخاص بنا. - نقوم بعد ذلك بتحديد أعمدة الرأس التي يجب أن يحتوي عليها ملف CSV ونمررها إلى كائن
csv.DictWriter
باستخدام وسيطة الكلمة الأساسيةfieldnames
. - بعد إنشاء ملف
csv.DictWriter
وتخزينه في متغيرwriter
، نستدعيwriter.writeheader()
. سيؤدي هذا إلى كتابة الرأس تلقائيًا في ملف CSV. - بعد ذلك، نستدعي
writer.writerow()
عدة مرات. ومع كل استدعاء، نوفر قاموسًا يمثل الصف الذي سيتم كتابته في ملف CSV. بطبيعة الحال، يجب أن تتطابق مفاتيح القاموس مع العنوان الذي حددناه مسبقًا.
إذا ألقيت نظرة على نظام الملفات، فستجد ملف names.csv
الذي تم إنشاؤه حديثًا. وبفحصه كجدول بيانات، سيتضح أن البيانات موجودة بالفعل!
اكتشاف المزيد من بايثون العربي
اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.