2017-06-28 3 views
3

En utilisant deux séries Pandas: série 1, et série 2, je suis prêt à faire série3. Chaque valeur de series1 est une liste et chaque valeur de series2 est un index correspondant de series1.Si la valeur de la série pandas est une liste, comment obtenir une sous-liste de chaque élément?

>>> print(series1) 

0  [481, 12, 11, 220, 24, 24, 645, 153, 15, 13, 6... 
1  [64, 80, 79, 147, 14, 20, 56, 288, 12, 208, 26... 
4  [5, 6, 152, 31, 295, 127, 711, 5, 271, 291, 11... 
5   [363, 121, 727, 249, 483, 122, 241, 494, 555] 
7  [112, 20, 41, 9, 104, 131, 26, 298, 65, 214, 1... 
9  [129, 797, 19, 151, 448, 47, 19, 106, 299, 144... 
11  [72, 35, 25, 200, 122, 5, 75, 30, 208, 24, 14,... 
18  [137, 339, 71, 14, 19, 54, 61, 15, 73, 104, 43... 



>>> print(series2) 

0  0 
1  3 
4  1 
5  6 
7  4 
9  5 
11  7 
18  2 

Ce que j'attends:

>>> print(series3) 

0  [481, 12, 11, 220, 24, 24, 645, 153, 15, 13, 6... 
1  [147, 14, 20, 56, 288, 12, 208, 26... 
4  [6, 152, 31, 295, 127, 711, 5, 271, 291, 11... 
5  [241, 494, 555] 
7  [104, 131, 26, 298, 65, 214, 1... 
9  [47, 19, 106, 299, 144... 
11  [30, 208, 24, 14,... 
18  [71, 14, 19, 54, 61, 15, 73, 104, 43... 

Ma solution 1: Du fait que la longueur de série1 et series2 sont égaux, je pourrais faire une boucle pour itérer série1 et de calculer quelque chose comme series1.ix[i][series2.ix[i]] et faire une nouvelle série (série3) pour enregistrer le résultat.

Ma solution 2: Générer une trame de données df utilisant df = pd_concat([series1, series2]), et faire une nouvelle colonne (opération de ligne sage à l'aide appliquer la fonction - par exemple, df [ 'series3'] = df.apply (lambda x: subList (x), axe = 1).

Cependant, je pensais au-dessus de deux solutions ne sont pas des moyens affûtés pour obtenir ce que je veux. Je vous serais reconnaissant si vous proposez des solutions plus nettes!

+0

Qu'est-ce que D'autres types de solutions espérais-tu? Essentiellement, vous allez devoir boucler vos lignes. 'pandas' n'a pas été conçu avec des valeurs' list's en tête, donc il n'y aura pas de fonctions intégrées pour accommoder des choses comme le découpage de liste vectorisé. La solution la plus «soignée» que je pourrais trouver est 'pd.concat ([S1, S2], axis = 1) .apply (lambda x: x [0] [x [1]:], axe = 1)' (en supposant que les "colonnes" seront de simples étiquettes entières) mais ceci n'est pas plus efficace que la simple boucle for que vous mentionnez. –

+0

En effet, regardez combien il est plus facile de travailler avec des listes Python: 'L1, L2 = S1.tolist(), S2.tolist()' alors simplement 'list (map (lambda x, y: x [y: ], L1, L2)) 'et c'est probablement aussi efficace (plus vraiment) que les opérations' pandas '. –

+0

1. Je ne voulais pas faire de dataFrame copié pour effectuer ce calcul. J'espère que quelqu'un connaît la meilleure réponse que cela. 2. Il est un peu dangereux de convertir la série en liste dans mon cas. Une erreur de calcul pourrait être faite si les indices sont ignorés. – SUNDONG

Répondre

3

Si vous espérez pour éviter de créer un pd.DataFrame intermédiaire, et veulent tout simplement une nouvelle pd.Series, vous pouvez utiliser le constructeur pd.Series sur un objet map. Donc, étant donné:

In [6]: S1 
Out[6]: 
0 [481, 12, 11, 220, 24, 24, 645, 153, 15, 13, 6] 
1 [64, 80, 79, 147, 14, 20, 56, 288, 12, 208, 26] 
2 [5, 6, 152, 31, 295, 127, 711, 5, 271, 291, 11] 
3  [363, 121, 727, 249, 483, 122, 241, 494, 555] 
4 [112, 20, 41, 9, 104, 131, 26, 298, 65, 214, 1] 
5 [129, 797, 19, 151, 448, 47, 19, 106, 299, 144] 
6  [72, 35, 25, 200, 122, 5, 75, 30, 208, 24, 14] 
7 [137, 339, 71, 14, 19, 54, 61, 15, 73, 104, 43] 
dtype: object 

In [7]: S2 
Out[7]: 
0 0 
1 3 
2 1 
3 6 
4 4 
5 5 
6 7 
7 2 
dtype: int64 

Vous pouvez faire:

In [8]: pd.Series(map(lambda x,y : x[y:], S1, S2), index=S1.index) 
Out[8]: 
0 [481, 12, 11, 220, 24, 24, 645, 153, 15, 13, 6] 
1    [147, 14, 20, 56, 288, 12, 208, 26] 
2  [6, 152, 31, 295, 127, 711, 5, 271, 291, 11] 
3         [241, 494, 555] 
4     [104, 131, 26, 298, 65, 214, 1] 
5       [47, 19, 106, 299, 144] 
6         [30, 208, 24, 14] 
7    [71, 14, 19, 54, 61, 15, 73, 104, 43] 
dtype: object 

Si vous voulez modifier S1 sans créer un récipient intermédiaire, vous pouvez utiliser une boucle for:

In [10]: for i, x in enumerate(map(lambda x,y : x[y:], S1, S2)): 
    ...:  S1.iloc[i] = x 
    ...: 

In [11]: S1 
Out[11]: 
0 [481, 12, 11, 220, 24, 24, 645, 153, 15, 13, 6] 
1    [147, 14, 20, 56, 288, 12, 208, 26] 
2  [6, 152, 31, 295, 127, 711, 5, 271, 291, 11] 
3         [241, 494, 555] 
4     [104, 131, 26, 298, 65, 214, 1] 
5       [47, 19, 106, 299, 144] 
6         [30, 208, 24, 14] 
7    [71, 14, 19, 54, 61, 15, 73, 104, 43] 
dtype: object 
0

vous pouvez preÂcisant série essentiellement concaténer axe Wich (0 = rangée, 1 colonne), mieux être de la même longueur

series3=pd.concat([series2, series1], axis=1).reset_index()