pandas python شرح




حذف العمود من pandas DataFrame باستخدام del df.column_name (8)

Pandas 0.21+ الجواب

لقد قام الباندا الإصدار 0.21 بتغيير أسلوب الإسقاط بشكل طفيف ليشمل كلاً من معلمات index columns لتتطابق مع توقيع طريقتين rename و reindex .

df.drop(columns=['column_a', 'column_c'])

أنا شخصياً أفضل استخدام معلمة axis للإشارة إلى الأعمدة أو الفهرس لأنها معلمة الكلمة الرئيسية السائدة المستخدمة في جميع طرق الباندا تقريبًا. ولكن الآن لديك بعض الخيارات المضافة في الإصدار 0.21.

عند حذف عمود في DataFrame أستخدم:

del df['column_name']

وهذا يعمل بشكل رائع. لماذا لا يمكنني استخدام:

del df.column_name

كما يمكنك الوصول إلى العمود / السلسلة كـ df.column_name ، أتوقع أن يعمل هذا.


TL، DR

الكثير من الجهد لإيجاد حل أكثر فعالية بشكل هامشي. من الصعب تبرير التعقيد الإضافي مع التضحية ببساطة df.drop(dlst, 1, errors='ignore')

df.reindex_axis(np.setdiff1d(df.columns.values, dlst), 1)

مقدمة
حذف أحد الأعمدة هو نفسه مثل تحديد الأعمدة الأخرى. سوف أعرض بعض الطرق الإضافية للنظر فيها.

سأركز أيضًا على الحل العام لحذف عدة أعمدة دفعة واحدة والسماح بمحاولة حذف الأعمدة غير الموجودة.

استخدام هذه الحلول عام وسيعمل في حالة بسيطة كذلك.

اقامة
جرب pd.DataFrame df وقائمة حذف dlst

df = pd.DataFrame(dict(zip('ABCDEFGHIJ', range(1, 11))), range(3))
dlst = list('HIJKLM')
df

   A  B  C  D  E  F  G  H  I   J
0  1  2  3  4  5  6  7  8  9  10
1  1  2  3  4  5  6  7  8  9  10
2  1  2  3  4  5  6  7  8  9  10
dlst

['H', 'I', 'J', 'K', 'L', 'M']

يجب أن تبدو النتيجة كما يلي:

df.drop(dlst, 1, errors='ignore')

   A  B  C  D  E  F  G
0  1  2  3  4  5  6  7
1  1  2  3  4  5  6  7
2  1  2  3  4  5  6  7

بما أنني أقوم بمساواة حذف عمود لتحديد الأعمدة الأخرى ، فسوف أقوم بتجزئته إلى نوعين:

  1. اختيار التسمية
  2. اختيار منطقي

اختيار التسمية

نبدأ بتصنيع قائمة / مجموعة من التصنيفات التي تمثل الأعمدة التي نريد الاحتفاظ بها وبدون الأعمدة التي نريد حذفها.

  1. df.columns.difference(dlst)

    Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object')
    
  2. np.setdiff1d(df.columns.values, dlst)

    array(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype=object)
    
  3. df.columns.drop(dlst, errors='ignore')

    Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object')
    
  4. list(set(df.columns.values.tolist()).difference(dlst))

    # does not preserve order
    ['E', 'D', 'B', 'F', 'G', 'A', 'C']
    
  5. [x for x in df.columns.values.tolist() if x not in dlst]

    ['A', 'B', 'C', 'D', 'E', 'F', 'G']
    

أعمدة من العلامات
من أجل مقارنة عملية الاختيار ، افترض:

 cols = [x for x in df.columns.values.tolist() if x not in dlst]

ثم يمكننا تقييم

  1. df.loc[:, cols]
  2. df[cols]
  3. df.reindex(columns=cols)
  4. df.reindex_axis(cols, 1)

التي جميع تقييم ل:

   A  B  C  D  E  F  G
0  1  2  3  4  5  6  7
1  1  2  3  4  5  6  7
2  1  2  3  4  5  6  7

شريحة منطقية

يمكننا بناء صفيف / قائمة booleans للتقطيع

  1. ~df.columns.isin(dlst)
  2. ~np.in1d(df.columns.values, dlst)
  3. [x not in dlst for x in df.columns.values.tolist()]
  4. (df.columns.values[:, None] != dlst).all(1)

أعمدة من منطقية
من أجل المقارنة

bools = [x not in dlst for x in df.columns.values.tolist()]
  1. df.loc[: bools]

التي جميع تقييم ل:

   A  B  C  D  E  F  G
0  1  2  3  4  5  6  7
1  1  2  3  4  5  6  7
2  1  2  3  4  5  6  7

توقيت قوي

المهام

setdiff1d = lambda df, dlst: np.setdiff1d(df.columns.values, dlst)
difference = lambda df, dlst: df.columns.difference(dlst)
columndrop = lambda df, dlst: df.columns.drop(dlst, errors='ignore')
setdifflst = lambda df, dlst: list(set(df.columns.values.tolist()).difference(dlst))
comprehension = lambda df, dlst: [x for x in df.columns.values.tolist() if x not in dlst]

loc = lambda df, cols: df.loc[:, cols]
slc = lambda df, cols: df[cols]
ridx = lambda df, cols: df.reindex(columns=cols)
ridxa = lambda df, cols: df.reindex_axis(cols, 1)

isin = lambda df, dlst: ~df.columns.isin(dlst)
in1d = lambda df, dlst: ~np.in1d(df.columns.values, dlst)
comp = lambda df, dlst: [x not in dlst for x in df.columns.values.tolist()]
brod = lambda df, dlst: (df.columns.values[:, None] != dlst).all(1)

اختبارات

res1 = pd.DataFrame(
    index=pd.MultiIndex.from_product([
        'loc slc ridx ridxa'.split(),
        'setdiff1d difference columndrop setdifflst comprehension'.split(),
    ], names=['Select', 'Label']),
    columns=[10, 30, 100, 300, 1000],
    dtype=float
)

res2 = pd.DataFrame(
    index=pd.MultiIndex.from_product([
        'loc'.split(),
        'isin in1d comp brod'.split(),
    ], names=['Select', 'Label']),
    columns=[10, 30, 100, 300, 1000],
    dtype=float
)

res = res1.append(res2).sort_index()

dres = pd.Series(index=res.columns, name='drop')

for j in res.columns:
    dlst = list(range(j))
    cols = list(range(j // 2, j + j // 2))
    d = pd.DataFrame(1, range(10), cols)
    dres.at[j] = timeit('d.drop(dlst, 1, errors="ignore")', 'from __main__ import d, dlst', number=100)
    for s, l in res.index:
        stmt = '{}(d, {}(d, dlst))'.format(s, l)
        setp = 'from __main__ import d, dlst, {}, {}'.format(s, l)
        res.at[(s, l), j] = timeit(stmt, setp, number=100)

rs = res / dres
rs

                          10        30        100       300        1000
Select Label                                                           
loc    brod           0.747373  0.861979  0.891144  1.284235   3.872157
       columndrop     1.193983  1.292843  1.396841  1.484429   1.335733
       comp           0.802036  0.732326  1.149397  3.473283  25.565922
       comprehension  1.463503  1.568395  1.866441  4.421639  26.552276
       difference     1.413010  1.460863  1.587594  1.568571   1.569735
       in1d           0.818502  0.844374  0.994093  1.042360   1.076255
       isin           1.008874  0.879706  1.021712  1.001119   0.964327
       setdiff1d      1.352828  1.274061  1.483380  1.459986   1.466575
       setdifflst     1.233332  1.444521  1.714199  1.797241   1.876425
ridx   columndrop     0.903013  0.832814  0.949234  0.976366   0.982888
       comprehension  0.777445  0.827151  1.108028  3.473164  25.528879
       difference     1.086859  1.081396  1.293132  1.173044   1.237613
       setdiff1d      0.946009  0.873169  0.900185  0.908194   1.036124
       setdifflst     0.732964  0.823218  0.819748  0.990315   1.050910
ridxa  columndrop     0.835254  0.774701  0.907105  0.908006   0.932754
       comprehension  0.697749  0.762556  1.215225  3.510226  25.041832
       difference     1.055099  1.010208  1.122005  1.119575   1.383065
       setdiff1d      0.760716  0.725386  0.849949  0.879425   0.946460
       setdifflst     0.710008  0.668108  0.778060  0.871766   0.939537
slc    columndrop     1.268191  1.521264  2.646687  1.919423   1.981091
       comprehension  0.856893  0.870365  1.290730  3.564219  26.208937
       difference     1.470095  1.747211  2.886581  2.254690   2.050536
       setdiff1d      1.098427  1.133476  1.466029  2.045965   3.123452
       setdifflst     0.833700  0.846652  1.013061  1.110352   1.287831
fig, axes = plt.subplots(2, 2, figsize=(8, 6), sharey=True)
for i, (n, g) in enumerate([(n, g.xs(n)) for n, g in rs.groupby('Select')]):
    ax = axes[i // 2, i % 2]
    g.plot.bar(ax=ax, title=n)
    ax.legend_.remove()
fig.tight_layout()

هذا نسبة إلى الوقت المستغرق لتشغيل df.drop(dlst, 1, errors='ignore') . يبدو بعد كل هذا الجهد ، نحن فقط نحسن الأداء بشكل متواضع.

إذا كانت أفضل الحلول هي استخدام reindex أو reindex_axis في list(set(df.columns.values.tolist()).difference(dlst)) الاختراق list(set(df.columns.values.tolist()).difference(dlst)) . ثاني وثيق جدا و np.setdiff1d جدا جدا من drop هو np.setdiff1d .

rs.idxmin().pipe(
    lambda x: pd.DataFrame(
        dict(idx=x.values, val=rs.lookup(x.values, x.index)),
        x.index
    )
)

                      idx       val
10     (ridx, setdifflst)  0.653431
30    (ridxa, setdifflst)  0.746143
100   (ridxa, setdifflst)  0.816207
300    (ridx, setdifflst)  0.780157
1000  (ridxa, setdifflst)  0.861622

أفضل طريقة للقيام بذلك في حيوانات الباندا هي استخدام drop :

df = df.drop('column_name', 1)

حيث 1 هو رقم المحور ( 0 للصفوف و 1 للأعمدة.)

لحذف العمود دون الحاجة إلى إعادة تعيين df يمكنك القيام بما يلي:

df.drop('column_name', axis=1, inplace=True)

أخيرًا ، لإسقاط رقم العمود بدلاً من تصنيف العمود ، حاول حذف هذا ، على سبيل المثال ، الأعمدة الأولى والثانية والرابعة:

df.drop(df.columns[[0, 1, 3]], axis=1)  # df.columns is zero-based pd.Index 

إضافة لطيفة هي القدرة على إسقاط الأعمدة فقط إذا كانت موجودة ، وبهذه الطريقة يمكنك تغطية المزيد من حالات الاستخدام ، وستسقط فقط الأعمدة الموجودة من التسميات التي تم تمريرها إليها:

ببساطة إضافة أخطاء = "تجاهل" ، على سبيل المثال:

df.drop(['col_name_1','col_name_2',...,'col_name_N'],inplace=True,axis=1,errors='ignore')
  • هذا جديد من الباندا 0.16.1 ، والمستندات here

بناء الجملة النقطية يعمل في JS ولكن ليس في python .

بايثون : del df ['column_name']

JS : del df ['column_name'] أو del df.column_name


في الباندا 0.16.1+ يمكنك إسقاط الأعمدة فقط إذا كانت موجودة في الحل الذي نشرهeiTanLaVi. قبل هذا الإصدار ، يمكنك تحقيق النتيجة نفسها عبر فهم قائمة مشروط:

df.drop([col for col in ['col_name_1','col_name_2',...,'col_name_N'] if col in df], 
        axis=1, inplace=True)

من الممارسات الجيدة دائمًا استخدام الترميز [] ، أحد الأسباب هو أن ترميز السمة ( df.column_name ) لا يعمل للمؤشرات المرقمة:

In [1]: df = DataFrame([[1, 2, 3], [4, 5, 6]])

In [2]: df[1]
Out[2]: 
0    2
1    5
Name: 1

In [3]: df.1
  File "<ipython-input-3-e4803c0d1066>", line 1
    df.1
       ^
SyntaxError: invalid syntax

يصعب عمل del df.column_name ببساطة كنتيجة للقيود النحوية في Python. del df[name] إلى df.__delitem__(name) تحت الأغطية بواسطة Python.





dataframe