পান্ডাস কলামে কোনও তালিকা থেকে সমস্ত উপাদান রয়েছে কিনা তা পরীক্ষা করুন


20

আমার এই মত একটি df আছে:

frame = pd.DataFrame({'a' : ['a,b,c', 'a,c,f', 'b,d,f','a,z,c']})

এবং আইটেমগুলির একটি তালিকা:

letters = ['a','c']

আমার লক্ষ্যটি হ'ল frameকমপক্ষে 2 টি উপাদান থাকা সমস্ত সারিগুলি থেকে পাওয়াletters

আমি এই সমাধানটি নিয়ে এসেছি:

for i in letters:
    subframe = frame[frame['a'].str.contains(i)]

এটি আমাকে যা দিতে চায় তা দেয় তবে এটি স্কেলাবিলিটির দিক থেকে সেরা সমাধান নাও হতে পারে। কোন 'vectorised' সমাধান আছে? ধন্যবাদ


4
এটি আপনাকে কেবল সারি দেবে যা শেষ অক্ষরটি ধারণ করে কারণ আপনি কোনও পুনরাবৃত্তিতে সাবফ্রেমকে ওভাররাইড করেন
টম রন

আপনি @TomRon ডান, কি একটা সাঙ্ঘাতিক ভুল :)
Kauber

উত্তর:


12

আমি সিরিজের একটি তালিকা তৈরি করব এবং তারপরে একটি ভেক্টরাইজড প্রয়োগ করব np.all:

contains = [frame['a'].str.contains(i) for i in letters]
resul = frame[np.all(contains, axis=0)]

এটি প্রত্যাশা অনুযায়ী দেয়:

       a
0  a,b,c
1  a,c,f
3  a,z,c

3
অভিনন্দন 100k!
পিটার হাদাদ

14

একটি উপায় হ'ল ব্যবহার করে তালিকায় কলাম মানগুলি বিভক্ত করা str.splitএবং প্রাপ্ত তালিকাগুলির set(letters)মধ্যে একটি কিনা তা পরীক্ষা করা subset:

letters_s = set(letters)
frame[frame.a.str.split(',').map(letters_s.issubset)]

     a
0  a,b,c
1  a,c,f
3  a,z,c

মাপকাঠি:

def serge(frame):
    contains = [frame['a'].str.contains(i) for i in letters]
    return frame[np.all(contains, axis=0)]

def yatu(frame):
    letters_s = set(letters)
    return frame[frame.a.str.split(',').map(letters_s.issubset)]

def austin(frame):
    mask =  frame.a.apply(lambda x: np.intersect1d(x.split(','), letters).size > 0)
    return frame[mask]

def datanovice(frame):
    s = frame['a'].str.split(',').explode().isin(letters).groupby(level=0).cumsum()
    return frame.loc[s[s.ge(2)].index.unique()]

perfplot.show(
    setup=lambda n: pd.concat([frame]*n, axis=0).reset_index(drop=True), 

    kernels=[
        lambda df: serge(df),
        lambda df: yatu(df),
        lambda df: df[df['a'].apply(lambda x: np.all([*map(lambda l: l in x, letters)]))],
        lambda df: austin(df),
        lambda df: datanovice(df),
    ],

    labels=['serge', 'yatu', 'bruno','austin', 'datanovice'],
    n_range=[2**k for k in range(0, 18)],
    equality_check=lambda x, y: x.equals(y),
    xlabel='N'
)

এখানে চিত্র বর্ণনা লিখুন


আমি TypeError: unhashable type: 'set'আপনার কোড চালানোর সময় আমি পেতে পারি ? এটি সরবরাহ করা ফ্রেমের অ্যাবোতে
চালিয়ে

কি সংস্করণ? @Datanovice ডাবল চেক এবং সব জরিমানা বলে মনে হয়
yatu

আমার পান্ডাসটি রয়েছে 1.0.3এবং অজগর 3.7সম্ভবত কেবলমাত্র আমি
দাতানোভিস

3
@ দাতানোভিস আমার কাছে মনে হয় এর জন্য আপনার অজগর 3.8 প্রয়োজন :)
এঙ্কে

2
ধন্যবাদ, আমি @ দাতানোভিসের মতো একই ত্রুটি পেয়েছি এবং দুর্ভাগ্যক্রমে অজগর 3.8 তে লাফিয়ে উঠতে পারি না
কাউবার

7

আপনি ব্যবহার করতে পারেন np.intersect1d:

import pandas as pd
import numpy as np

frame = pd.DataFrame({'a' : ['a,b,c', 'a,c,f', 'b,d,f','a,z,c']})
letters = ['a','c']

mask =  frame.a.apply(lambda x: np.intersect1d(x.split(','), letters).size > 0)
print(frame[mask])

    a
0  a,b,c
1  a,c,f
3  a,z,c


6

Set.issubset ব্যবহার করুন :

frame = pd.DataFrame({'a' : ['a,b,c', 'a,c,f', 'b,d,f','a,z,c','x,y']})
letters = ['a','c']

frame[frame['a'].apply(lambda x: set(letters).issubset(x))]

Out:

       a
0  a,b,c
1  a,c,f
3  a,z,c

5

আইআইইউসি, explodeএবং একটি বুলিয়ান ফিল্টার

ধারণাটি হ'ল একটি একক সিরিজ তৈরি করা যায় তারপরে আমরা ক্রমসংখ্যক যোগ ব্যবহার করে আপনার তালিকার সত্যিকারের উপস্থিতিগুলি তালিকাভুক্ত করতে পারি we

s = frame['a'].str.split(',').explode().isin(letters).groupby(level=0).cumsum()

print(s)

0    1.0
0    1.0
0    2.0
1    1.0
1    2.0
1    2.0
2    0.0
2    0.0
2    0.0
3    1.0
3    1.0
3    2.0

frame.loc[s[s.ge(2)].index.unique()]

out:

       a
0  a,b,c
1  a,c,f
3  a,z,c

1
frame.iloc[[x for x in range(len(frame)) if set(letters).issubset(frame.iloc[x,0])]]

আউটপুট:

        a
 0  a,b,c
 1  a,c,f
 3  a,z,c

timeit

%%timeit
#hermes
frame.iloc[[x for x in range(len(frame)) if set(letters).issubset(frame.iloc[x,0])]]

আউটপুট

300 µs ± 32.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.