Filtre dataframe lignes si la valeur dans la colonne est dans une liste de valeurs

j'ai une DataFrame Python pandas rpt :

rpt
<class 'pandas.core.frame.DataFrame'>
MultiIndex: 47518 entries, ('000002', '20120331') to ('603366', '20091231')
Data columns:
STK_ID                    47518  non-null values
STK_Name                  47518  non-null values
RPT_Date                  47518  non-null values
sales                     47518  non-null values

je peux filtrer les lignes dont le stock id est '600809' comme ceci: rpt[rpt['STK_ID'] == '600809']

<class 'pandas.core.frame.DataFrame'>
MultiIndex: 25 entries, ('600809', '20120331') to ('600809', '20060331')
Data columns:
STK_ID                    25  non-null values
STK_Name                  25  non-null values
RPT_Date                  25  non-null values
sales                     25  non-null values

et je veux réunir toutes les rangées de certains stocks, comme ['600809','600141','600329'] . Cela signifie que je veux une syntaxe comme celle-ci:

stk_list = ['600809','600141','600329']

rst = rpt[rpt['STK_ID'] in stk_list] # this does not works in pandas 

puisque pandas n'accepte pas au-dessus du commandement, comment atteindre l'objectif?

298
demandé sur firelynx 2012-08-22 07:16:56

7 réponses

utilisez la méthode isin . rpt[rpt['STK_ID'].isin(stk_list)] .

448
répondu BrenBarn 2012-08-22 03:21:12

isin() est idéal si vous avez une liste de correspondances exactes, mais si vous avez une liste de correspondances partielles ou de substrats à rechercher, vous pouvez filtrer en utilisant la méthode str.contains et des expressions régulières.

par exemple, si nous voulons retourner une base de données où tous les numéros d'identification de stock qui commencent par '600' et sont ensuite suivis de n'importe quels trois chiffres:

>>> rpt[rpt['STK_ID'].str.contains(r'^600[0-9]{3}$')] # ^ means start of string
...   STK_ID   ...                                    # [0-9]{3} means any three digits
...  '600809'  ...                                    # $ means end of string
...  '600141'  ...
...  '600329'  ...
...      ...   ...

Supposons maintenant que nous avons une liste de chaînes que nous voulons que les valeurs de 'STK_ID' se terminent par, par exemple

endstrings = ['01$', '02$', '05$']

nous pouvons joindre ces chaînes avec le caractère regex ' ou ' | et passer la chaîne à str.contains pour filtrer la base de données:

>>> rpt[rpt['STK_ID'].str.contains('|'.join(endstrings)]
...   STK_ID   ...
...  '155905'  ...
...  '633101'  ...
...  '210302'  ...
...      ...   ...

enfin, contains peut ignorer case (en définissant case=False ), vous permettant d'être plus général en spécifiant les chaînes que vous voulez associer.

par exemple,

str.contains('pandas', case=False)

correspondrait PANDAS , PanDAs , paNdAs123 , et ainsi de suite.

90
répondu Alex Riley 2015-04-12 18:29:27

vous pouvez également utiliser des gammes en utilisant:

b = df[(df['a'] > 1) & (df['a'] < 5)]
38
répondu yemu 2013-10-10 12:26:29

vous pouvez aussi directement demander votre DataFrame pour cette information.

rpt.query('STK_ID in (600809,600141,600329)')

ou recherche similaire de plages:

rpt.query('60000 < STK_ID < 70000')
35
répondu bscan 2015-10-27 15:39:51

découpage de données avec pandas

avec une base de données comme celle-ci:

    RPT_Date  STK_ID STK_Name  sales
0 1980-01-01       0   Arthur      0
1 1980-01-02       1    Beate      4
2 1980-01-03       2    Cecil      2
3 1980-01-04       3     Dana      8
4 1980-01-05       4     Eric      4
5 1980-01-06       5    Fidel      5
6 1980-01-07       6   George      4
7 1980-01-08       7     Hans      7
8 1980-01-09       8   Ingrid      7
9 1980-01-10       9    Jones      4

il existe plusieurs façons de sélectionner ou de découper les données.

en utilisant .isin

la caractéristique la plus évidente est .isin . Vous pouvez créer un masque qui vous donne une série de déclarations True / False , qui peuvent être appliquées à une base de données comme celle-ci:

mask = df['STK_ID'].isin([4, 2, 6])

mask
0    False
1    False
2     True
3    False
4     True
5    False
6     True
7    False
8    False
9    False
Name: STK_ID, dtype: bool

df[mask]
    RPT_Date  STK_ID STK_Name  sales
2 1980-01-03       2    Cecil      2
4 1980-01-05       4     Eric      4
6 1980-01-07       6   George      4

Masquage est la solution ad hoc au problème, mais ne fonctionne pas toujours bien en termes de vitesse et de mémoire.

avec indexation

en réglant l'index sur la colonne STK_ID , nous pouvons utiliser l'objet de tranchage .loc

df.set_index('STK_ID', inplace=True)
         RPT_Date STK_Name  sales
STK_ID                           
0      1980-01-01   Arthur      0
1      1980-01-02    Beate      4
2      1980-01-03    Cecil      2
3      1980-01-04     Dana      8
4      1980-01-05     Eric      4
5      1980-01-06    Fidel      5
6      1980-01-07   George      4
7      1980-01-08     Hans      7
8      1980-01-09   Ingrid      7
9      1980-01-10    Jones      4

df.loc[[4, 2, 6]]
         RPT_Date STK_Name  sales
STK_ID                           
4      1980-01-05     Eric      4
2      1980-01-03    Cecil      2
6      1980-01-07   George      4

C'est le moyen rapide de le faire, même si l'indexation peut prendre un peu de temps, il permet de gagner du temps si vous voulez faire plusieurs requêtes de ce genre.

Fusion dataframes

cela peut aussi être fait en fusionnant des images de données. Cela correspondrait plus pour un scénario où vous avez beaucoup plus de données que dans ces exemples.

stkid_df = pd.DataFrame({"STK_ID": [4,2,6]})
df.merge(stkid_df, on='STK_ID')
   STK_ID   RPT_Date STK_Name  sales
0       2 1980-01-03    Cecil      2
1       4 1980-01-05     Eric      4
2       6 1980-01-07   George      4

Note

toutes les méthodes ci-dessus fonctionnent même s'Il ya plusieurs lignes avec le même 'STK_ID'

16
répondu firelynx 2017-04-27 13:30:50

vous pouvez utiliser query , i.e.:

b = df.query('a > 1 & a < 5')
5
répondu Pedro Lobito 2017-04-26 20:09:12

vous pouvez également obtenir des résultats similaires en utilisant "query" et@:

par exemple:

df = pd.DataFrame({'A': [1, 2, 3], 'B': ['a', 'b', 'f']})
df = pd.DataFrame({'A' : [5,6,3,4], 'B' : [1,2,3, 5]})
list_of_values = [3,6]
result= df.query("A in @list_of_values")
result
   A  B
1  6  2
2  3  3
4
répondu akuriako 2017-09-28 03:04:39