पांडा डेटाफ़्रेम में नए कॉलम में सूची में मिली आईडी जोड़ें


11

मान लें कि मेरे पास निम्नलिखित डेटाफ़्रेम (पूर्णांक का एक स्तंभ और पूर्णांक की सूची वाला एक स्तंभ) है ...

      ID                   Found_IDs
0  12345        [15443, 15533, 3433]
1  15533  [2234, 16608, 12002, 7654]
2   6789      [43322, 876544, 36789]

और आईडी की एक अलग सूची भी ...

bad_ids = [15533, 876544, 36789, 11111]

यह देखते हुए, और df['ID']कॉलम और किसी भी सूचकांक को अनदेखा करते हुए , मैं यह देखना चाहता हूं कि क्या bad_idsसूची में मौजूद किसी भी आईडी का उल्लेख df['Found_IDs']कॉलम में है। मेरे पास अब तक का कोड है:

df['bad_id'] = [c in l for c, l in zip(bad_ids, df['Found_IDs'])]

यह काम करता है लेकिन केवल अगर bad_idsसूची डेटाफ्रेम से अधिक लंबी है और वास्तविक डेटासेट के लिए bad_idsसूची डेटाफ्रेम की तुलना में बहुत छोटी होने जा रही है। अगर मैं bad_idsसूची को केवल दो तत्वों पर सेट करता हूं ...

bad_ids = [15533, 876544]

मुझे बहुत लोकप्रिय त्रुटि मिलती है (मैंने एक ही त्रुटि के साथ कई प्रश्न पढ़े हैं) ...

ValueError: Length of values does not match length of index

मैंने सूची को एक श्रृंखला में बदलने की कोशिश की है (त्रुटि में कोई बदलाव नहीं)। मैंने नए कॉलम को जोड़ने और सभी मूल्यों को स्थापित करने Falseसे पहले समझने की कोशिश की है (फिर से त्रुटि में कोई बदलाव नहीं)।

दो सवाल:

  1. डेटाफ़्रेम से छोटी सूची के लिए काम करने के लिए मुझे अपना कोड (नीचे) कैसे मिलेगा?
  2. मुझे df['bad_id']कॉलम में वापस पाई गई वास्तविक आईडी लिखने के लिए कोड कैसे मिलेगा (ट्रू / फाल्स की तुलना में अधिक उपयोगी)?

इसके लिए अपेक्षित उत्पादन bad_ids = [15533, 876544]:

      ID                   Found_IDs  bad_id
0  12345        [15443, 15533, 3433]    True
1  15533  [2234, 16608, 12002, 7654]   False
2   6789      [43322, 876544, 36789]    True

आदर्श bad_ids = [15533, 876544]पहचान (आईडी) नए कॉलम या कॉलम के लिए लिखी गई हैं:

      ID                   Found_IDs  bad_id
0  12345        [15443, 15533, 3433]    15533
1  15533  [2234, 16608, 12002, 7654]   False
2   6789      [43322, 876544, 36789]    876544

कोड:

import pandas as pd

result_list = [[12345,[15443,15533,3433]],
        [15533,[2234,16608,12002,7654]],
        [6789,[43322,876544,36789]]]

df = pd.DataFrame(result_list,columns=['ID','Found_IDs'])

# works if list has four elements
# bad_ids = [15533, 876544, 36789, 11111]

# fails if list has two elements (less elements than the dataframe)
# ValueError: Length of values does not match length of index
bad_ids = [15533, 876544]

# coverting to Series doesn't change things
# bad_ids = pd.Series(bad_ids)
# print(type(bad_ids))

# setting up a new column of false values doesn't change things
# df['bad_id'] = False

print(df)

df['bad_id'] = [c in l for c, l in zip(bad_ids, df['Found_IDs'])]

print(bad_ids)

print(df)

जवाबों:


7

np.intersect1dदो सूचियों के प्रतिच्छेद प्राप्त करने के लिए उपयोग करना :

df['bad_id'] = df['Found_IDs'].apply(lambda x: np.intersect1d(x, bad_ids))

      ID                   Found_IDs    bad_id
0  12345        [15443, 15533, 3433]   [15533]
1  15533  [2234, 16608, 12002, 7654]        []
2   6789      [43322, 876544, 36789]  [876544]

या सिर्फ वेनिला अजगर के साथ sets:

bad_ids_set = set(bad_ids)
df['Found_IDs'].apply(lambda x: list(set(x) & bad_ids_set))

3

यदि आप उपयोग के Found_IDsसभी मूल्यों के कॉलम में सूचियों के सभी मूल्यों का परीक्षण करना चाहते bad_idsहैं:

bad_ids = [15533, 876544]

df['bad_id'] = [any(c in l for c in bad_ids) for l  in df['Found_IDs']]
print (df)
      ID                   Found_IDs  bad_id
0  12345        [15443, 15533, 3433]    True
1  15533  [2234, 16608, 12002, 7654]   False
2   6789      [43322, 876544, 36789]    True

यदि सभी मैच चाहते हैं:

df['bad_id'] = [[c for c in bad_ids if c in l] for l  in df['Found_IDs']]
print (df)
      ID                   Found_IDs    bad_id
0  12345        [15443, 15533, 3433]   [15533]
1  15533  [2234, 16608, 12002, 7654]        []
2   6789      [43322, 876544, 36789]  [876544]

और पहले मैच के लिए, यदि खाली सूची सेट की गई है False, तो संभव समाधान, लेकिन बूलियन और संख्याओं को मिलाने की अनुशंसा नहीं की गई है:

df['bad_id'] = [next(iter([c for c in bad_ids if c in l]), False) for l  in df['Found_IDs']]
print (df)
      ID                   Found_IDs  bad_id
0  12345        [15443, 15533, 3433]   15533
1  15533  [2234, 16608, 12002, 7654]   False
2   6789      [43322, 876544, 36789]  876544

सेट के साथ समाधान:

df['bad_id'] = df['Found_IDs'].map(set(bad_ids).intersection)
print (df)

      ID                   Found_IDs    bad_id
0  12345        [15443, 15533, 3433]   {15533}
1  15533  [2234, 16608, 12002, 7654]        {}
2   6789      [43322, 876544, 36789]  {876544}

और सूची बोध के साथ भी समान:

df['bad_id'] = [list(set(bad_ids).intersection(l)) for l  in df['Found_IDs']]
print (df)
      ID                   Found_IDs    bad_id
0  12345        [15443, 15533, 3433]   [15533]
1  15533  [2234, 16608, 12002, 7654]        []
2   6789      [43322, 876544, 36789]  [876544]

1

आप लागू कर सकते हैं और np.any का उपयोग कर सकते हैं:

df['bad_id'] = df['Found_IDs'].apply(lambda x: np.any([c in x for c in bad_ids]))

यदि आप इस bad_ids को पुनः प्राप्त करना चाहते हैं, तो यह bad_id को फाउंड_आईडी में मौजूद होने पर बूल लौटाता है:

df['bad_id'] = df['Found_IDs'].apply(lambda x: [*filter(lambda x: c in x, bad_ids)])

यह फाउंड_ पर bad_ids की सूची लौटाएगा, अगर 0 है तो यह रिटर्न करता है []


1

सभी मैचों को वापस करने के लिए अपने इंडेक्स द्वारा समूहीकरण का उपयोग करना mergeऔर concatwhilst करना।

bad_ids = [15533, 876544, 36789, 11111]

df2 = pd.concat(
    [
        df,
        pd.merge(
            df["Found_IDs"].explode().reset_index(),
            pd.Series(bad_ids, name="bad_ids"),
            left_on="Found_IDs",
            right_on="bad_ids",
            how="inner",
        )
        .groupby("index")
        .agg(bad_ids=("bad_ids", list)),
    ],
    axis=1,
).fillna(False)
print(df2)


      ID                   Found_IDs          bad_ids
0  12345        [15443, 15533, 3433]          [15533]
1  15533  [2234, 16608, 12002, 7654]            False
2   6789      [43322, 876544, 36789]  [876544, 36789]

0

एक्सप्लोड और ग्रुपबी एग्रीगेट का उपयोग करें

s = df['Found_IDs'].explode()
df['bad_ids'] = s.isin(bad_ids).groupby(s.index).any()

के लिये bad_ids = [15533, 876544]

>>> df
      ID                   Found_IDs  bad_ids
0  12345        [15443, 15533, 3433]     True
1  15533  [2234, 16608, 12002, 7654]    False
2   6789      [43322, 876544, 36789]     True

या

मूल्यों के मिलान के लिए

s = df['Found_IDs'].explode()
s.where(s.isin(bad_ids)).groupby(s.index).agg(lambda x: list(x.dropna()))

के लिये bad_ids = [15533, 876544]

      ID                   Found_IDs   bad_ids
0  12345        [15443, 15533, 3433]   [15533]
1  15533  [2234, 16608, 12002, 7654]        []
2   6789      [43322, 876544, 36789]  [876544]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.