web-dev-qa-db-fra.com

sous-ensemble a Python DataFrame

Je suis en train de passer de R à Python. Je viens de commencer à utiliser des pandas. J'ai un code R qui sous-ensemble bien:

k1 <- subset(data, Product = p.id & Month < mn & Year == yr, select = c(Time, Product))

Maintenant, je veux faire des choses similaires en Python. Voici ce que j'ai jusqu'à présent:

import pandas as pd
data = pd.read_csv("../data/monthly_prod_sales.csv")


#first, index the dataset by Product. And, get all that matches a given 'p.id' and time.
 data.set_index('Product')
 k = data.ix[[p.id, 'Time']]

# then, index this subset with Time and do more subsetting..

Je commence à sentir que je le fais de la mauvaise façon. peut-être, il y a une solution élégante. Quelqu'un peut-il aider? Je dois extraire le mois et l’année de l’horodatage que j’ai et faire un sous-réglage. Peut-être y a-t-il un one-line qui accomplira tout ceci:

k1 <- subset(data, Product = p.id & Time >= start_time & Time < end_time, select = c(Time, Product))

merci.

53
user1717931

Je suppose que Time et Product sont des colonnes dans un DataFrame, df est une instance de DataFrame et que d'autres variables sont des valeurs scalaires:

Pour l'instant, vous devrez référencer l'instance DataFrame:

k1 = df.loc[(df.Product == p_id) & (df.Time >= start_time) & (df.Time < end_time), ['Time', 'Product']]

Les parenthèses sont également nécessaires, en raison de la priorité de l'opérateur & Par rapport aux opérateurs de comparaison. L'opérateur & Est en fait un opérateur au niveau du bit surchargé qui a la même priorité que les opérateurs arithmétiques, qui ont à leur tour une priorité plus élevée que les opérateurs de comparaison.

Dans pandas 0.13 une nouvelle méthode expérimentale DataFrame.query() sera disponible. C'est très similaire au sous-ensemble modulo l'argument select:

Avec query(), vous le feriez comme ceci:

df[['Time', 'Product']].query('Product == p_id and Month < mn and Year == yr')

Voici un exemple simple:

In [9]: df = DataFrame({'gender': np.random.choice(['m', 'f'], size=10), 'price': poisson(100, size=10)})

In [10]: df
Out[10]:
  gender  price
0      m     89
1      f    123
2      f    100
3      m    104
4      m     98
5      m    103
6      f    100
7      f    109
8      f     95
9      m     87

In [11]: df.query('gender == "m" and price < 100')
Out[11]:
  gender  price
0      m     89
4      m     98
9      m     87

La dernière requête qui vous intéresse sera même capable de tirer parti des comparaisons chaînées, comme ceci:

k1 = df[['Time', 'Product']].query('Product == p_id and start_time <= Time < end_time')
88
Phillip Cloud

Juste pour quelqu'un qui recherche une solution plus semblable à R:

df[(df.Product == p_id) & (df.Time> start_time) & (df.Time < end_time)][['Time','Product']]

Pas besoin d data.loc ou query, mais je pense que c'est un peu long.

20
sernle

J'ai constaté que vous pouvez utiliser n'importe quelle condition de sous-ensemble pour une colonne donnée en l'enveloppant dans []. Par exemple, vous avez un df avec des colonnes ['Produit', 'Heure', 'Année', 'Couleur']

Et disons que vous voulez inclure les produits fabriqués avant 2014. Vous pouvez écrire,

df[df['Year'] < 2014]

Pour renvoyer toutes les lignes où c'est le cas. Vous pouvez ajouter différentes conditions.

df[df['Year'] < 2014][df['Color' == 'Red']

Ensuite, choisissez simplement les colonnes que vous voulez comme indiqué ci-dessus. Par exemple, la couleur du produit et la clé pour le df ci-dessus,

df[df['Year'] < 2014][df['Color' == 'Red'][['Product','Color']]
12
gpicard