অধ্যায় 4 · ডেটার জন্য Python
pandas: টেবিল নিয়ে কাজ
- পৃষ্ঠা 14 / 20
- 4 মিনিট পড়া
বেশিরভাগ আসল ডেটা আসে টেবিল হিসেবে: একটা স্প্রেডশিটের এক্সপোর্ট, ডেটাবেসের কোয়েরি, আপনার অ্যাপের প্রতিটা API কলের লগ। টেবিলের জন্য Python লাইব্রেরি হলো pandas। এর DataFrame যেন কোড দিয়ে চালানো একটা স্প্রেডশিট — আর মডেলের কাছে যাওয়ার আগে ডেটা পরিষ্কার করতে প্রত্যেক ডেটা সায়েন্টিস্টের রোজকার হাতিয়ার।
ইনস্টল করুন python -m pip install pandas দিয়ে; প্রথা অনুযায়ী ইমপোর্ট করা হয় pd নামে। উদাহরণগুলো কাস্টমার-সাপোর্টের টিকিটের এই ছোট ফাইলটা ব্যবহার করে, tickets.csv (খেয়াল করুন, T4-এর satisfaction স্কোর নেই):
ticket_id,channel,category,minutes_to_resolve,satisfaction
T1,email,billing,45,4
T2,chat,technical,12,5
T3,chat,billing,8,5
T4,phone,technical,30,
T5,email,account,60,2
T6,chat,technical,15,4
T7,phone,billing,25,3
T8,email,technical,90,1লোড করা আর দেখা
import pandas as pd
df = pd.read_csv("tickets.csv")
print(df.head(3))
print(df.shape)
print(df.dtypes) ticket_id channel category minutes_to_resolve satisfaction
0 T1 email billing 45 4.0
1 T2 chat technical 12 5.0
2 T3 chat billing 8 5.0
(8, 5)
ticket_id str
channel str
category str
minutes_to_resolve int64
satisfaction float64
dtype: objectসবসময় আগে দেখুন: head() ওপরের সারিগুলো দেখায়, shape দেয় (সারি, কলাম), আর dtypes দেখায় প্রতিটা কলামের জন্য pandas কোন টাইপ বেছেছে। খেয়াল করুন, satisfaction হয়েছে float64, int64 নয়: অনুপস্থিত মানটা রাখা হয়েছে NaN ("not a number") হিসেবে, যা শুধু float-ই রাখতে পারে। লেখার কলামগুলো str। বাঁ দিকের সংখ্যাগুলো হলো ইনডেক্স, সারির লেবেল।
কলাম বাছাই আর সারি ছাঁকা
import pandas as pd
df = pd.read_csv("tickets.csv")
print(df["minutes_to_resolve"].mean()) # একটা কলাম হলো Series
print(df[["ticket_id", "channel"]].tail(2)) # কলামের লিস্ট দিলে DataFrame
slow = df[df["minutes_to_resolve"] > 40] # শর্ত দিয়ে সারি ছাঁকা
print(slow[["ticket_id", "category", "minutes_to_resolve"]])
chat_billing = df[(df["channel"] == "chat") & (df["category"] == "billing")]
print(len(chat_billing), "chat billing ticket(s)")35.625
ticket_id channel
6 T7 phone
7 T8 email
ticket_id category minutes_to_resolve
0 T1 billing 45
4 T5 account 60
7 T8 technical 90
1 chat billing ticket(s)df["col"]দেয় একটা কলাম, একটা Series।df[["a", "b"]](দুই জোড়া বন্ধনী খেয়াল করুন) দেয় ছোট একটা DataFrame।df[condition]সেই সারিগুলো রাখে যেখানে শর্ত True — NumPy-র বুলিয়ান মাস্কের একই ধারণা।- শর্ত জুড়তে
&(এবং),|(অথবা),~(না) ব্যবহার করুন, আর প্রতিটা শর্ত বন্ধনীতে রাখুন। Python-এরand/orএখানে কাজ করে না।
কলাম যোগ, সাজানো আর গোনা
import pandas as pd
df = pd.read_csv("tickets.csv")
df["hours"] = (df["minutes_to_resolve"] / 60).round(2) # নতুন কলাম
df["is_slow"] = df["minutes_to_resolve"] > 40
df["label"] = df["category"].str.upper() + "/" + df["channel"] # .str দিয়ে লেখার মেথড
print(df[["ticket_id", "hours", "is_slow", "label"]].sort_values("hours", ascending=False).head(3))
print(df["channel"].value_counts()) ticket_id hours is_slow label
7 T8 1.50 True TECHNICAL/email
4 T5 1.00 True ACCOUNT/email
0 T1 0.75 True BILLING/email
channel
email 3
chat 3
phone 2
Name: count, dtype: int64নতুন কলাম লুপ ছাড়াই সব সারির জন্য একসাথে হিসাব হয়। লেখার কলামে আছে একটা .str, যাতে পাতা ৪-এ শেখা স্ট্রিং মেথডগুলো পাবেন।
দলে ভাগ করে সারাংশ
"প্রতি চ্যানেলে সমাধানের গড় সময় কত?" — এটা একটা group-by: সারিগুলো দলে ভাগ করো, প্রতিটা দলের সারাংশ করো, ফলাফলগুলো জোড়া লাগাও:
import pandas as pd
df = pd.read_csv("tickets.csv")
summary = df.groupby("channel").agg(
tickets=("ticket_id", "count"),
avg_minutes=("minutes_to_resolve", "mean"),
avg_satisfaction=("satisfaction", "mean"),
).round(1)
print(summary.sort_values("avg_minutes")) tickets avg_minutes avg_satisfaction
channel
chat 3 11.7 4.7
phone 2 27.5 3.0
email 3 65.0 2.3চ্যাটে সমাধান সবচেয়ে দ্রুত আর গ্রাহক সবচেয়ে খুশি; ইমেইল সবচেয়ে ধীর। কয়েক লাইনেই কাঁচা সারি থেকে এমন একটা তথ্য বের হলো, যার ভিত্তিতে সিদ্ধান্ত নেওয়া যায়।
অনুপস্থিত ডেটা
আসল ডেটায় সবসময় ফাঁক থাকে। খুঁজে বের করুন, তারপর ঠিক করুন: একটা যুক্তিসঙ্গত মান দিয়ে পূরণ করবেন, নাকি অসম্পূর্ণ সারিগুলো বাদ দেবেন:
import pandas as pd
df = pd.read_csv("tickets.csv")
print(df.isna().sum()) # প্রতি কলামে কয়টা মান নেই
print(df[df["satisfaction"].isna()])
filled = df["satisfaction"].fillna(df["satisfaction"].median())
print(filled.tolist())
print(len(df.dropna()), "rows have no missing values")
df.to_csv("tickets_clean.csv", index=False)ticket_id 0
channel 0
category 0
minutes_to_resolve 0
satisfaction 1
dtype: int64
ticket_id channel category minutes_to_resolve satisfaction
3 T4 phone technical 30 NaN
[4.0, 5.0, 5.0, 4.0, 2.0, 4.0, 3.0, 1.0]
7 rows have no missing valuesকোনটা ঠিক, তা প্রশ্নের ওপর নির্ভর করে। মিডিয়ান দিয়ে পূরণ করলে সব টিকিট থাকে; আন্দাজের মান বিভ্রান্ত করতে পারলে বাদ দেওয়াই নিরাপদ। যেটাই হোক, জেনে-বুঝে সিদ্ধান্ত নিন — গড় হিসাব করার সময় pandas NaN বাদ দেয়, যা কতটা ডেটা অনুপস্থিত তা চুপচাপ লুকিয়ে ফেলতে পারে। to_csv() ফলাফলটা সংরক্ষণ করে।
একটা AI প্রজেক্টের আগে কাজের বড় অংশই ঠিক এটা: ডেটা লোড করা, ফাঁক আর ভুল খুঁজে বের করা, আর আকার দেওয়া। এলোমেলো ডেটায় ট্রেনিং বা মূল্যায়ন করা মডেল এলোমেলো ফলাফলই দেয়।
নিজে চেষ্টা করুন
- কোন category-তে গড় satisfaction সবচেয়ে কম, বের করুন।
fastনামে একটা কলাম যোগ করুন, যা True হবে যখন টিকিটে ১৫ মিনিট বা কম লেগেছে, আর প্রতি চ্যানেলে দ্রুত টিকিট গুনুন।- শুধু technical টিকিটগুলো সমাধানের সময় অনুযায়ী সাজিয়ে
technical.csv-এ এক্সপোর্ট করুন।