मेरे पास मूवी शीर्षक और शैलियों के साथ कॉलम के साथ डेटाफ्रेम है। जैसे 'वन' शीर्षक वाली फिल्म 'एक्शन' और 'वेस्टर्न' है, क्योंकि उपयुक्त कॉलम में '1' है।

   Movie  Action  Fantasy  Vestern
0    One       1        0        1
1    Two       0        0        1
2  Three       1        1        0

मेरा लक्ष्य कॉलम genres बनाना है, जिसमें प्रत्येक शैली का नाम होगा, जो उस विशेष फिल्म में है। इसके लिए मुझे lambda और list comprehension इस्तेमाल करने की कोशिश की गई, क्योंकि सोचा कि इससे मदद मिलती है। लेकिन कोड की इस तरह की लाइन चलाने के बाद:

df['genres'] = df.apply(lambda x: [x+"|"+x for x in df.columns if x!=0])

मुझे प्रत्येक पंक्ति में केवल NaN मान मिला है:

   Movie  Action  Fantasy  Vestern genres
0    One       1        0        1    NaN
1    Two       0        0        1    NaN
2  Three       1        1        0    NaN

groupby का उपयोग करने का भी प्रयास किया, लेकिन सफल नहीं हुआ।

अपेक्षित आउटपुट है:

   Movie  Action  Fantasy  Vestern          genres
0    One       1        0        1  Action|Vestern
1    Two       0        0        1         Vestern
2  Three       1        1        0  Action|Fantasy

पुन: पेश करने के लिए कोड:

import pandas as pd
import numpy as np

df = pd.DataFrame({"Movie":['One','Two','Three'],
                   "Action":[1,0,1],
                   "Fantasy":[0,0,1],
                   "Vestern":[1,1,0]})
print(df)

आपकी सहायता के लिए धन्यवाद

1
Dmitriy Kisil 8 जिंदा 2019, 16:05

2 जवाब

सबसे बढ़िया उत्तर

बेहतर प्रदर्शन के लिए dot< का उपयोग करना संभव है। /a> बिना पहले वाले सभी कॉलम, बिना आखिरी वाले सभी कॉलम separator, आखिरी वाले | को rstrip:

df['new'] = df.iloc[:, 1:].dot(df.columns[1:] + '|').str.rstrip('|')
print (df)
   Movie  Action  Fantasy  Vestern             new
0    One       1        0        1  Action|Vestern
1    Two       0        0        1         Vestern
2  Three       1        1        0  Action|Fantasy

या खाली स्ट्रिंग के बिना सभी मानों में शामिल होने के लिए सूची समझ का उपयोग करें:

arr = df.iloc[:, 1:].values * df.columns[1:].values
df['new'] = ['|'.join(y for y in x if y) for x in arr]
print (df)
   Movie  Action  Fantasy  Vestern             new
0    One       1        0        1  Action|Vestern
1    Two       0        0        1         Vestern
2  Three       1        1        0  Action|Fantasy

प्रदर्शन:

In [54]: %timeit (jez1(df.copy()))
25.2 ms ± 2.31 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [55]: %timeit (jez2(df.copy()))
61.4 ms ± 769 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [56]: %timeit (csm(df.copy()))
1.46 s ± 35.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)



df = pd.DataFrame({"Movie":['One','Two','Three'],
                   "Action":[1,0,1],
                   "Fantasy":[0,0,1],
                   "Vestern":[1,1,0]})
#print(df)

#30k rows
df = pd.concat([df] * 10000, ignore_index=True)

def csm(df):
    cols = df.columns.tolist()[1:]
    df['genres'] = df.apply(lambda x: "|".join(str(z) for z in [i for i in cols if x[i] !=0]) ,axis=1)
    return df

def jez1(df):
    df['new'] = df.iloc[:, 1:].dot(df.columns[1:] + '|').str.rstrip('|')
    return df

def jez2(df):
    arr = df.iloc[:, 1:].values * df.columns[1:].values
    df['new'] = ['|'.join(y for y in x if y) for x in arr]
    return df
1
jezrael 8 जिंदा 2019, 16:23
import pandas as pd
import numpy as np

df = pd.DataFrame({"Movie":['One','Two','Three'],
                   "Action":[1,0,1],
                   "Fantasy":[0,0,1],
                   "Vestern":[1,1,0]})

cols = df.columns.tolist()[1:]

df['genres'] = df.apply(lambda x: "|".join(str(z) for z in [i for i in cols if x[i] !=0]) ,axis=1)
print(df)

उत्पादन

Movie  Action  Fantasy  Vestern          genres
0    One       1        0        1  Action|Vestern
1    Two       0        0        1         Vestern
2  Three       1        1        0  Action|Fantasy
1
CSMaverick 8 जिंदा 2019, 16:12