web-dev-qa-db-fra.com

Comment prendre des tranches de colonnes de données dans des pandas

Je charge des données d'apprentissage machine à partir d'un fichier CSV. Les 2 premières colonnes sont des observations et les colonnes restantes sont des entités.

Actuellement, je fais ce qui suit:

data = pandas.read_csv('mydata.csv')

ce qui donne quelque chose comme:

data = pandas.DataFrame(np.random.Rand(10,5), columns = list('abcde'))

J'aimerais découper cette base de données en deux bases de données: une contenant les colonnes a et b et l'autre contenant les colonnes c, d et e.

Il n'est pas possible d'écrire quelque chose comme 

observations = data[:'c']
features = data['c':]

Je ne sais pas quelle est la meilleure méthode. Ai-je besoin d'un pd.Panel?

En passant, je trouve l'indexation de la structure de données assez incohérente: data['a'] est autorisé, mais data[0] ne l'est pas. De l'autre côté, data['a':] n'est pas autorisé mais data[0:] est . Y a-t-il une raison pratique à cela? C'est vraiment déroutant si les colonnes sont indexées par Int, étant donné que data[0] != data[0:1]

204
cpa

Réponse de 2017 - pandas 0,20: .ix est obsolète. Utilisez .loc

Voir la obsolète dans la documentation

.loc utilise l'indexation basée sur une étiquette pour sélectionner les lignes et les colonnes. Les étiquettes étant les valeurs de l'index ou des colonnes. Le découpage avec .loc inclut le dernier élément. 

Supposons que nous avons un DataFrame avec les colonnes suivantes:
foo, bar, quz, ant, cat, sat, dat.

# selects all rows and all columns beginning at 'foo' up to and including 'sat'
df.loc[:, 'foo':'sat']
# foo bar quz ant cat sat

.loc accepte la même notation de tranche que les listes Python pour les lignes et les colonnes. La notation de tranche étant start:stop:step

# slice from 'foo' to 'cat' by every 2nd column
df.loc[:, 'foo':'cat':2]
# foo quz cat

# slice from the beginning to 'bar'
df.loc[:, :'bar']
# foo bar

# slice from 'quz' to the end by 3
df.loc[:, 'quz'::3]
# quz sat

# attempt from 'sat' to 'bar'
df.loc[:, 'sat':'bar']
# no columns returned

# slice from 'sat' to 'bar'
df.loc[:, 'sat':'bar':-1]
sat cat ant quz bar

# slice notation is syntatic sugar for the slice function
# slice from 'quz' to the end by 2 with slice function
df.loc[:, slice('quz',None, 2)]
# quz cat dat

# select specific columns with a list
# select columns foo, bar and dat
df.loc[:, ['foo','bar','dat']]
# foo bar dat

Vous pouvez découper par rangées et par colonnes. Par exemple, si vous avez 5 lignes avec des étiquettes v, w, x, y, z

# slice from 'w' to 'y' and 'foo' to 'ant' by 3
df.loc['w':'y', 'foo':'ant':3]
#    foo ant
# w
# x
# y
163
Ted Petrou

L'index DataFrame.ix est ce que vous voulez accéder. C'est un peu déroutant (je conviens que l'indexation des Pandas est parfois déroutante!), Mais ce qui suit semble faire ce que vous voulez:

>>> df = DataFrame(np.random.Rand(4,5), columns = list('abcde'))
>>> df.ix[:,'b':]
      b         c         d         e
0  0.418762  0.042369  0.869203  0.972314
1  0.991058  0.510228  0.594784  0.534366
2  0.407472  0.259811  0.396664  0.894202
3  0.726168  0.139531  0.324932  0.906575

où .ix [tranche de ligne, tranche de colonne] est ce qui est interprété. Plus d'informations sur l'indexation des pandas ici: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-advanced

Remarque:.ix est obsolète depuis Pandas v0.20. Vous devriez plutôt utiliser .loc ou .iloc, selon le cas.

146
Karmel

Utilisons à titre d'exemple l'ensemble de données titanesque du paquet Seaborn

# Load dataset (pip install seaborn)
>> import seaborn.apionly as sns
>> titanic = sns.load_dataset('titanic')

en utilisant les noms de colonne

>> titanic.loc[:,['sex','age','fare']]

en utilisant les index de colonne

>> titanic.iloc[:,[2,3,6]]

using ix (Older than Pandas <.20 version)

>> titanic.ix[:,[‘sex’,’age’,’fare’]]

ou

>> titanic.ix[:,[2,3,6]]

en utilisant la méthode de réindexation

>> titanic.reindex(columns=['sex','age','fare'])
62
jetpackdata.com

En outre, étant donné un DataFrame 

les données

comme dans votre exemple, si vous souhaitez extraire les colonnes a et d uniquement (par exemple, les colonnes 1 et 4), iloc mothod du cadre de données pandas est ce dont vous avez besoin et peut être utilisé de manière très efficace. Tout ce que vous devez savoir, c'est l'index des colonnes que vous souhaitez extraire. Par exemple:

>>> data.iloc[:,[0,3]]

te donnera

          a         d
0  0.883283  0.100975
1  0.614313  0.221731
2  0.438963  0.224361
3  0.466078  0.703347
4  0.955285  0.114033
5  0.268443  0.416996
6  0.613241  0.327548
7  0.370784  0.359159
8  0.692708  0.659410
9  0.806624  0.875476
32
moldovean

Vous pouvez découper le long des colonnes d'une DataFrame en vous référant aux noms de chaque colonne d'une liste, comme suit:

data = pandas.DataFrame(np.random.Rand(10,5), columns = list('abcde'))
data_ab = data[list('ab')]
data_cde = data[list('cde')]
24
Brendan Wood

Et si vous êtes venu ici pour couper deux rangées de colonnes et les combiner (comme moi), vous pouvez faire quelque chose comme: 

op = df[list(df.columns[0:899]) + list(df.columns[3593:])]
print op

Cela créera un nouveau cadre de données avec 900 premières colonnes et (toutes) colonnes> 3593 (en supposant que votre jeu de données contienne environ 4000 colonnes). 

18
user2023507

Voici comment vous pouvez utiliser différentes méthodes pour effectuer le découpage sélectif des colonnes, y compris le découpage sélectif des colonnes basé sur des étiquettes, des index et des plages sélectives.

In [37]: import pandas as pd    
In [38]: import numpy as np
In [43]: df = pd.DataFrame(np.random.Rand(4,7), columns = list('abcdefg'))

In [44]: df
Out[44]: 
          a         b         c         d         e         f         g
0  0.409038  0.745497  0.890767  0.945890  0.014655  0.458070  0.786633
1  0.570642  0.181552  0.794599  0.036340  0.907011  0.655237  0.735268
2  0.568440  0.501638  0.186635  0.441445  0.703312  0.187447  0.604305
3  0.679125  0.642817  0.697628  0.391686  0.698381  0.936899  0.101806

In [45]: df.loc[:, ["a", "b", "c"]] ## label based selective column slicing 
Out[45]: 
          a         b         c
0  0.409038  0.745497  0.890767
1  0.570642  0.181552  0.794599
2  0.568440  0.501638  0.186635
3  0.679125  0.642817  0.697628

In [46]: df.loc[:, "a":"c"] ## label based column ranges slicing 
Out[46]: 
          a         b         c
0  0.409038  0.745497  0.890767
1  0.570642  0.181552  0.794599
2  0.568440  0.501638  0.186635
3  0.679125  0.642817  0.697628

In [47]: df.iloc[:, 0:3] ## index based column ranges slicing 
Out[47]: 
          a         b         c
0  0.409038  0.745497  0.890767
1  0.570642  0.181552  0.794599
2  0.568440  0.501638  0.186635
3  0.679125  0.642817  0.697628

### with 2 different column ranges, index based slicing: 
In [49]: df[df.columns[0:1].tolist() + df.columns[1:3].tolist()]
Out[49]: 
          a         b         c
0  0.409038  0.745497  0.890767
1  0.570642  0.181552  0.794599
2  0.568440  0.501638  0.186635
3  0.679125  0.642817  0.697628
10
Surya

Son équivalent

 >>> print(df2.loc[140:160,['Relevance','Title']])
 >>> print(df2.ix[140:160,[3,7]])
0
Max Kleiner

Une autre façon d’obtenir un sous-ensemble de colonnes de votre DataFrame, en supposant que vous souhaitiez toutes les lignes, serait de procéder comme suit:
data[['a','b']] et data[['c','d','e']]
Si vous voulez utiliser des index de colonnes numériques, vous pouvez faire:
data[data.columns[:2]] et data[data.columns[2:]]

0
Camilo

si le cadre de données ressemble à cela:

group         name      count
fruit         Apple     90
fruit         banana    150
fruit         orange    130
vegetable     broccoli  80
vegetable     kale      70
vegetable     lettuce   125

et OUTPUT pourrait être comme

   group    name  count
0  fruit   Apple     90
1  fruit  banana    150
2  fruit  orange    130

si vous utilisez l'opérateur logique np.logical_not

df[np.logical_not(df['group'] == 'vegetable')]

plus à propos 

https://docs.scipy.org/doc/numpy-1.13.0/reference/routines.logic.html

autres opérateurs logiques 

  1. logical_and (x1, x2,/[ out, where, ...]) Calcule la valeur de vérité de x1 AND x2 par élément. 

  2. logical_or (x1, x2,/[ out, où, casting, ...]) Calcule la valeur de vérité de x1 OR x2 par élément.

  3. logical_not (x,/[ out, où, casting, ...]) Calcule la vérité valeur de NOT x élément en ce qui concerne. 
  4. logical_xor (x1, x2,/[ out, où, ..]) Calcule la valeur de vérité de x1 XOR x2, élément par élément.
0
Vladimir Gavrysh