2017-07-20 6 views
2

Il me manque la conversion spontanée et facile de longue à large et vice versa en Python. Imaginez, j'ai un grand dataframe bien rangé avec beaucoup de propriété colonnes et une seule colonne qui contient toutes les valeurs réelles commepivot Python Pandas: Comment faire une bonne propagation de type Tidyr?

PropA ... PropZ Value 
green  Saturn 400 
green  Venus 3 
red  Venus 2 
. 
. 

Les données lui-même est très bien géré en le mettant bien rangé. Mais parfois, je dois effectuer certaines actions sur certaines propriétés (par exemple, il peut être intéressant de comparer le rouge par rapport au vert en cours de développement (pour tous les éléments qui sont similaires aux autres propriétés)). Donc, la façon la plus simple serait de garder le plus de rangement possible et de ne désordonner que la propriété qui m'intéresse (PropA). Par la suite, je pourrais exécuter une carte rangée-sage avec n'importe quelle fonction que je désire et je pourrais créer un PropA-Entrée supplémentaire qui contient la fonction-ouput. Cependant, garder toutes les autres propriétés ordonnées n'est pas aussi facile en Python que ce à quoi j'ai été habitué en utilisant R. La raison en est que toutes les propriétés non-pivotantes sont abandonnées à l'index avec toutes les méthodes-pd que j'ai trouvées . C'est tout un gâchis si j'ai d'autres colonnes que je veux garder.

Alors comment vous entendez-vous avec ce problème. Y a-t-il une autre façon de traiter ce genre de problèmes? J'ai écrit moi-même une méthode de propagation, mais elle est terriblement lente. Peut-être, vous avez quelques idées comment je peux améliorer.

#the idea is to group by the remaining properties, which should be left in the long format. 
#then i spread the small tidy data table for any group 
    @staticmethod 
    def spread(df, propcol, valcol): 
     def flip(data,pc,vc): 
      data = data.reset_index(drop=True) 
      return {data[pc][i]:[data[vc][i]] for i in range(0,len(data))} 

     #index columns are all which are not affected 
     indcols = list(df.columns) 
     indcols.remove(propcol) 
     indcols.remove(valcol) 

     tmpdf=pd.DataFrame() 
     for key, group in df.groupby(indcols): 
      dc1 = {a:[b] for (a,b) in zip(indcols,key)} 
      dc2 = flip(group,propcol,valcol) 
      tmpdf = pd.concat([tmpdf,pd.concat([pd.DataFrame(dc1),pd.DataFrame(dc2)],axis=1)]) 

     return tmpdf.reset_index(drop = True) 
+0

Un multi-index ne serait-il pas suffisant? Il y a une explication raisonnable [ici] (https://stackoverflow.com/questions/35414625/pandas-how-to-run-a-pivot-with-a-multi-index) – asongtoruin

+0

thx pour le lien. cela signifie-t-il: il est préférable d'organiser les données ordonnées par indexation hiérarchique? Par conséquent, je devrais ranger toutes mes données en passant toutes les propriétés à l'index et en ne gardant que la colonne de valeur. mais cela semble un peu gênant, puisque la majorité des informations sont capturées dans l'index. De plus, mes propriétés sont interchangeables et pas vraiment hiérarchiques. – Antalagor

Répondre

1

Avec l'aide de l'indice, j'ai créé une version plus simple. Je suis encore un peu confus avec le mécanicien d'index, mais le temps m'aidera à mieux comprendre.

def spread(df, propcol, valcol): 
    indcol = list(df.columns.drop(valcol)) 
    df = df.set_index(indcol).unstack(propcol).reset_index() 
    df.columns = [i[1] if i[0] == valcol else i[0] for i in df.columns] 
    return df