Je suis dans un peu de cornichon

J'ai une trame de données:

Old_DF

    Date.               Year    On/Off      Gender. Status.    
0   2019-03-14 09:59:30 Senior  Off Campus  Male    Full Time
1   2019-03-13 15:56:13 Senior  Off Campus  Male    Full Time

La première trame de données a une colonne qui demande aux gens de classer certaines choses, mais en raison de la sagesse infinie du format d'exportation de Jotform, il prend leur classement personnel et le met dans une chaîne par cellule afin:

0   2019-03-14 09:59:30 Senior  Off Campus  Male    Full Time   1Food\r 2Lounge or Study Space\r 3Retail\r 4Ev...   NaN
1   2019-03-13 15:56:13 Senior  Off Campus  Male    Full Time   1Lounge or Study Space\r 2Food\r 3Academic Res...   NaN

Mon idée consiste essentiellement à diviser la chaîne en mots clés et à leur attribuer une valeur de lettre, c'est-à-dire "Food" = 'A', 'Lounge or Study Space' = 'B'

À partir de cela, je voudrais essentiellement convertir la chaîne en toute combinaison possible de "ABCDEFG", et l'ajouter en tant que nouvelle colonne avec uniquement la combinaison de lettres, puis compter la combinaison la plus élevée.

  'Combo'                 
0  'ABCDEFG'    
1  'BDCFGAE'    

Mes problèmes sont mathématiques, c'est beaucoup de combinaisons ou c'est la seule,

Voici ce que j'ai écrit jusqu'à présent

clean_3 = 

rank
0  food lounge or study space retail event space ...
1  lounge or study space food academic resources ...

Combo_list = []
    small_combo_list = []
    for i in clean_3:

        if clean_3[i] == 'food':
            Combo_list.append('A')

        elif clean_3[i] == 'lounge or study space':
            Combo_list.append('B')

        elif clean_3[i] == 'retail':
            Combo_list.append('C')

        elif  clean_3[i] == 'event space':
            Combo_list.append('D')

        elif  clean_3[i] == 'academic resources':
            Combo_list.append('E')

        elif  clean_3[i] == 'student life':
            NCombo_list.append('F')

        elif  clean_3[i] == 'general services':
            Combo_list.append('G')

        small_combo_list.append(Combo_list)

        print(small_combo_list)

Cependant, je reçois cette erreur:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

Ce qui n'a pas de sens (du moins pour moi) car c'est un dataframe pas une série.

Idéalement, s'il existe un moyen plus efficace de le faire, veuillez me faire tomber la tête, car la taille de ce csv est indéterminée. Faites-moi savoir si j'ai besoin d'expliquer autre chose!

EDIT: les deux seules lignes de la trame de données actuelle, et un témoignage de la lourdeur du format d'exportation des jotforms

    Date.               Year    On/Off      Gender. Status.     Rank
0   2019-03-14 09:59:30 Senior  Off Campus  Male    Full Time   1Food
                                                                2Lounge or Study Space
                                                                3Retail
                                                                4Event Space
                                                              5Academic Resources (Tutoring, Career Advice)
                                                               6Student Life (Student Involvement, Diversity Services)
                                                               7General Services (Lockers, Information Desk, Vending Machines)


    Date.               Year    On/Off      Gender. Status.     Rank
1   2019-03-14 09:59:30 Senior  Off Campus  Male    Full Time   1Food
                                                                2Lounge or Study Space
                                                                3Retail
                                                                4Event Space
                                                              5Academic Resources (Tutoring, Career Advice)
                                                               6Student Life (Student Involvement, Diversity Services)
                                                               7General Services (Lockers, Information Desk, Vending Machines)
1
Sebastian Goslin 14 mars 2019 à 20:44

2 réponses

Meilleure réponse

Ce serait mieux si j'avais plus d'exemples de données, difficiles à tester avec seulement deux lignes, mais voici quelque chose que vous pouvez essayer.

Nettoyez d'abord vos données avec .str.replace et .str.split. Après cela, je le convertis en type object.

Maintenant, nous avons tous les choix nettoyés et en ordre.

Nous pouvons donc simplement groupby et count comme suit:

# Dataframe I worked with
                  Date    Year      On/Off Gender     Status  \
0  2019-03-14 09:59:30  Senior  Off Campus   Male  Full Time   
1  2019-03-13 15:56:13  Senior  Off Campus   Male  Full Time   

                                             Ranking  
0  1Food\r 2Lounge or Study Space\r 3Retail\r 4Ev...  
1  1Lounge or Study Space\r 2Food\r 3Academic Res... 

# Clean up Ranking column
df['Ranking'] = df.Ranking.str.replace('\d+', '').str.split('\r').astype(str)

# Count the amount of choices and convert it to a column
df['times_chosen'] = df.groupby('Ranking').Ranking.transform('size')

Sortie

                                             Ranking  times_chosen
0  ['Food', ' Lounge or Study Space', ' Retail', ...             1
1  ['Lounge or Study Space', ' Food', ' Academic ...             1

2e option

Ne pas convertir en colonne, juste grouper

df.groupby('Ranking').Ranking.size()

Ranking
['Food', ' Lounge or Study Space', ' Retail', ' Ev...']    1
['Lounge or Study Space', ' Food', ' Academic Res...']     1
Name: Ranking, dtype: int64

Ou avec .agg

print(df.groupby('Ranking').agg({'Ranking': ['count']}))

                                                   Ranking
                                                     count
Ranking                                                   
['Food', ' Lounge or Study Space', ' Retail', '...       1
['Lounge or Study Space', ' Food', ' Academic R...       1
1
Erfan 14 mars 2019 à 18:35

Vous pouvez simplement utiliser groupby sur votre colonne d'origine (ou une version nettoyée) si la mise en forme est cohérente pour obtenir rapidement les décomptes:

df=pd.Series(
        {'rank': ['food lounge or study space retail event space ...',
                  'food lounge or study space retail event space ...',
                  'lounge or study space food academic resources ...',
                  'lounge or study space food academic resources ...',
                  'lounge or study space food academic resources ...']}, 
    dtype=str)

df.groupby('rank').size()

> rank
> food lounge or study space retail event space ...    2
> lounge or study space food academic resources ...    3
> dtype: int64
1
Nathaniel 14 mars 2019 à 18:42