جداول تتشارك مفتاحًا
نادرًا ما تصل البيانات الحقيقية في جدول واحد. مراكزك في جدول، وقطاع كل رمز في جدول آخر، والأسعار في ثالث. ما يربطها هو مفتاح، وهنا الرمز. يجد left.merge(right, on="key") لكل صف في left الصفوف ذات المفتاح نفسه في right ويضعها بجانبه. إنها الفكرة نفسها كالربط (join) في SQL.
import pandas as pd
positions = pd.DataFrame({"symbol": ["AAPL", "MSFT", "TSLA", "GOOG"], "qty": [100, 50, 20, 10]})
reference = pd.DataFrame({"symbol": ["AAPL", "MSFT", "GOOG", "F"], "sector": ["tech", "tech", "tech", "auto"]})
merged = positions.merge(reference, on="symbol")
print(merged)
# symbol qty sector
# 0 AAPL 100 tech
# 1 MSFT 50 tech
# 2 GOOG 10 techinner وleft وright وouter
اختفى TSLA من النتيجة أعلاه، واختفى F أيضًا. الافتراضي how="inner" يُبقي المفاتيح الموجودة في الجدولين فقط. حدّد ما تريد: يُبقي how="left" كل صفوف الجدول الأيسر ويملأ القيم الناقصة من اليمين بـ NaN، ويفعل how="right" العكس، ويُبقي how="outer" مفاتيح الجدولين. لإثراء جدول تريد left في الغالب لأنه لا يفقد صفًا بصمت.
# how="left" keeps every position; TSLA has no sector, so it gets NaN
left = positions.merge(reference, on="symbol", how="left")
print(left)
# symbol qty sector
# 0 AAPL 100 tech
# 1 MSFT 50 tech
# 2 TSLA 20 NaN
# 3 GOOG 10 tech
# how="outer" keeps the keys of both tables (sorted); quantities become floats because of the NaN
print(positions.merge(reference, on="symbol", how="outer"))
# symbol qty sector
# 0 AAPL 100.0 tech
# 1 F NaN auto
# 2 GOOG 10.0 tech
# 3 MSFT 50.0 tech
# 4 TSLA 20.0 NaNإيجاد ما لم يتطابق
قد يخفي NaN الصامت مشكلة في البيانات، لذا افحصه. يضيف indicator=True عمودًا _merge يبيّن لكل صف إن كان المفتاح وُجد في left_only أو right_only أو both. والترشيح عليه يجيب عن أسئلة مثل «أي المراكز بلا سعر؟». والمفاتيح المكررة فخ آخر: إن ظهر مفتاح مرتين في اليمين تتكرر كل صف مطابق في اليسار. مرّر validate="many_to_one" (أو "one_to_one") فتُطلق pandas خطأً بدل أن تغيّر عدد الصفوف بصمت.
# Which positions have no sector?
check = positions.merge(reference, on="symbol", how="left", indicator=True)
print(check)
# symbol qty sector _merge
# 0 AAPL 100 tech both
# 1 MSFT 50 tech both
# 2 TSLA 20 NaN left_only
# 3 GOOG 10 tech both
print(check.loc[check["_merge"] == "left_only", "symbol"].tolist()) # ['TSLA']# Duplicate keys repeat rows: AAPL has two quotes, so the AAPL position appears twice
quotes = pd.DataFrame({"symbol": ["AAPL", "AAPL", "MSFT"], "price": [184.25, 184.5, 410.1]})
print(len(positions.merge(quotes, on="symbol"))) # 3
# validate turns the surprise into an error
try:
positions.merge(quotes, on="symbol", validate="one_to_one")
except Exception as error:
print(type(error).__name__) # MergeErrorمفاتيح بأسماء مختلفة وأعمدة متعارضة
حين يختلف اسم المفتاح في الجدولين استخدم left_on="symbol", right_on="ticker" وسيُحتفظ بالعمودين. وحين يكون في الجدولين عمود بالاسم نفسه ليس هو المفتاح (هنا qty) تحتفظ pandas بكليهما وتضيف اللاحقتين _x و_y. اختر لاحقتين أوضح عبر suffixes=("_a", "_b"). وبعد الربط الخارجي تصبح الكميات الناقصة NaN ويصير العمود عشريًا: استخدم fillna(0) ثم astype("int64") لاستعادة الأعداد الصحيحة.
# Different key names: both columns are kept
book_a = pd.DataFrame({"symbol": ["AAPL", "MSFT"], "qty": [100, 50]})
book_b = pd.DataFrame({"ticker": ["MSFT", "TSLA"], "qty": [-20, 30]})
print(book_a.merge(book_b, left_on="symbol", right_on="ticker", how="outer", suffixes=("_a", "_b")))
# symbol qty_a ticker qty_b
# 0 AAPL 100.0 NaN NaN
# 1 MSFT 50.0 MSFT -20.0
# 2 NaN NaN TSLA 30.0
# Same key name, outer join, suffixes, then back to whole numbers
both = book_a.merge(book_b.rename(columns={"ticker": "symbol"}), on="symbol", how="outer", suffixes=("_a", "_b"))
both[["qty_a", "qty_b"]] = both[["qty_a", "qty_b"]].fillna(0).astype("int64")
print(both)
# symbol qty_a qty_b
# 0 AAPL 100 0
# 1 MSFT 50 -20
# 2 TSLA 0 30len() قبله وبعده، واستخدم how="left" حين تريد إبقاء كل الصفوف، وأضف validate= حين تعتقد أن المفاتيح فريدة.left.merge(right, on="key")يطابق صفوف جدولين يتشاركان مفتاحًا؛ ويعالجleft_on/right_onالأسماء المختلفة.how="inner"(الافتراضي) يُبقي المفاتيح المشتركة، و"left"كل صفوف اليسار، و"outer"كل المفاتيح.indicator=Trueيُظهر ما لم يتطابق؛ وvalidate=وsuffixes=يحميان من المفاتيح المكررة والأسماء المتعارضة.
التالي: العوائد البسيطة، أي تحويل سلسلة أسعار إلى نسبة التغير من فترة إلى التي تليها.
المختبر: ما الذي يُقيَّم
- أضف قطاع كل صفقة باستخدام
attach_sector25 نقطة - قيّم المراكز التي لها سعر باستخدام
value_positions25 نقطة - اعثر على المراكز بلا سعر باستخدام
unpriced_symbols25 نقطة - اجمع دفترين في جدول واحد باستخدام
combine_books25 نقطة