python - تصفية صفوف dataframe إذا كانت القيمة في العمود في قائمة قيم محددة




pandas (5)

لدي python pandas DataFrame rpt :

rpt
<class 'pandas.core.frame.DataFrame'>
MultiIndex: 47518 entries, ('000002', '20120331') to ('603366', '20091231')
Data columns:
STK_ID                    47518  non-null values
STK_Name                  47518  non-null values
RPT_Date                  47518  non-null values
sales                     47518  non-null values

يمكنني تصفية الصفوف التي يكون رقم '600809' كما يلي: rpt[rpt['STK_ID'] == '600809']

<class 'pandas.core.frame.DataFrame'>
MultiIndex: 25 entries, ('600809', '20120331') to ('600809', '20060331')
Data columns:
STK_ID                    25  non-null values
STK_Name                  25  non-null values
RPT_Date                  25  non-null values
sales                     25  non-null values

وأريد الحصول على جميع صفوف بعض الأسهم معًا ، مثل ['600809','600141','600329'] . هذا يعني أنني أريد بناء الجملة على النحو التالي:

stk_list = ['600809','600141','600329']

rst = rpt[rpt['STK_ID'] in stk_list] # this does not works in pandas 

منذ الباندا لا تقبل الأمر أعلاه ، وكيفية تحقيق الهدف؟


تقسيم البيانات مع الباندا

وبالنظر إلى dataframe مثل هذا:

    RPT_Date  STK_ID STK_Name  sales
0 1980-01-01       0   Arthur      0
1 1980-01-02       1    Beate      4
2 1980-01-03       2    Cecil      2
3 1980-01-04       3     Dana      8
4 1980-01-05       4     Eric      4
5 1980-01-06       5    Fidel      5
6 1980-01-07       6   George      4
7 1980-01-08       7     Hans      7
8 1980-01-09       8   Ingrid      7
9 1980-01-10       9    Jones      4

هناك طرق متعددة لتحديد البيانات أو تشريحها.

باستخدام

الأكثر وضوحًا هي ميزة .isin . يمكنك إنشاء قناع يمنحك سلسلة من عبارات True / False ، والتي يمكن تطبيقها على مخطط بيانات مثل:

mask = df['STK_ID'].isin([4, 2, 6])

mask
0    False
1    False
2     True
3    False
4     True
5    False
6     True
7    False
8    False
9    False
Name: STK_ID, dtype: bool

df[mask]
    RPT_Date  STK_ID STK_Name  sales
2 1980-01-03       2    Cecil      2
4 1980-01-05       4     Eric      4
6 1980-01-07       6   George      4

إن الإخفاء هو الحل المخصص للمشكلة ، ولكنه لا يعمل دائمًا بشكل جيد من حيث السرعة والذاكرة.

مع الفهرسة

من خلال تعيين الفهرس على عمود STK_ID ، يمكننا استخدام كائن تقطيع الباندا المدمج .loc

df.set_index('STK_ID', inplace=True)
         RPT_Date STK_Name  sales
STK_ID                           
0      1980-01-01   Arthur      0
1      1980-01-02    Beate      4
2      1980-01-03    Cecil      2
3      1980-01-04     Dana      8
4      1980-01-05     Eric      4
5      1980-01-06    Fidel      5
6      1980-01-07   George      4
7      1980-01-08     Hans      7
8      1980-01-09   Ingrid      7
9      1980-01-10    Jones      4

df.loc[[4, 2, 6]]
         RPT_Date STK_Name  sales
STK_ID                           
4      1980-01-05     Eric      4
2      1980-01-03    Cecil      2
6      1980-01-07   George      4

هذه هي الطريقة السريعة لفعل ذلك ، حتى إذا استغرقت الفهرسة بعض الوقت ، فهي توفر الوقت إذا كنت تريد إجراء عدة استعلامات مثل هذا.

دمج تدفقات البيانات

ويمكن أيضا أن يتم ذلك عن طريق دمج إطارات البيانات. هذا من شأنه أن يلائم بشكل أكبر سيناريو حيث لديك الكثير من البيانات أكثر من هذه الأمثلة.

stkid_df = pd.DataFrame({"STK_ID": [4,2,6]})
df.merge(stkid_df, on='STK_ID')
   STK_ID   RPT_Date STK_Name  sales
0       2 1980-01-03    Cecil      2
1       4 1980-01-05     Eric      4
2       6 1980-01-07   George      4

ملحوظة

تعمل جميع الطرق المذكورة أعلاه حتى إذا كانت هناك صفوف متعددة بها نفس 'STK_ID'


استخدم طريقة isin . rpt[rpt['STK_ID'].isin(stk_list)] .


يمكنك أيضًا استخدام النطاقات باستخدام:

b = df[(df['a'] > 1) & (df['a'] < 5)]

يمكنك أيضًا تحقيق نتائج مشابهة باستخدام "طلب البحث" و @:

على سبيل المثال:

df = pd.DataFrame({'A': [1, 2, 3], 'B': ['a', 'b', 'f']})
df = pd.DataFrame({'A' : [5,6,3,4], 'B' : [1,2,3, 5]})
list_of_values = [3,6]
result= df.query("A in @list_of_values")
result
   A  B
1  6  2
2  3  3

isin() مثالية إذا كان لديك قائمة من المطابقات التامة ، ولكن إذا كان لديك قائمة str.contains الجزئية أو سلاسل فرعية للبحث عنها ، فيمكنك التصفية باستخدام طريقة str.contains والتعابير العادية.

على سبيل المثال ، إذا أردنا إرجاع DataFrame حيث تكون جميع أرقام تعريف المخزون التي تبدأ بـ '600' ثم متبوعة بأربعة أرقام:

>>> rpt[rpt['STK_ID'].str.contains(r'^600[0-9]{3}$')] # ^ means start of string
...   STK_ID   ...                                    # [0-9]{3} means any three digits
...  '600809'  ...                                    # $ means end of string
...  '600141'  ...
...  '600329'  ...
...      ...   ...

لنفترض الآن أن لدينا قائمة بالسلاسل التي نريد أن تنتهي بها القيم في 'STK_ID' ، على سبيل المثال

endstrings = ['01$', '02$', '05$']

يمكننا الانضمام إلى هذه السلاسل باستخدام الحرف أو الحرف المعتاد | وقم بتمرير السلسلة إلى str.contains لتصفية DataFrame:

>>> rpt[rpt['STK_ID'].str.contains('|'.join(endstrings)]
...   STK_ID   ...
...  '155905'  ...
...  '633101'  ...
...  '210302'  ...
...      ...   ...

أخيرًا ، contains يمكن تجاهل الحالة (عن طريق إعداد case=False ) ، مما يسمح لك أن تكون أكثر عمومية عند تحديد السلاسل التي تريد مطابقتها.

فمثلا،

str.contains('pandas', case=False)

يتطابق مع PanDAs و paNdAs123 و paNdAs123 وما إلى ذلك.





dataframe