子集化Python DataFrame

use*_*931 56 python subset pandas

我正在从R转换到Python.我刚刚开始使用熊猫.我有一个R代码很好地子集:

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

现在,我想在Python中做类似的事情.这是我到目前为止所得到的:

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..
Run Code Online (Sandbox Code Playgroud)

我开始觉得我这样做是错误的.或许,有一个优雅的解决方案.有人可以帮忙吗?我需要从我的时间戳中提取月份和年份并进行子集化.也许有一个单行程将完成所有这些:

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

谢谢.

Phi*_*oud 89

我假设Time,并Product在一列DataFrame, df为的实例DataFrame,而其他变量是标值:

现在,您必须引用该DataFrame实例:

k1 = df.loc[(df.Product == p_id) & (df.Time >= start_time) & (df.Time < end_time), ['Time', 'Product']]
Run Code Online (Sandbox Code Playgroud)

由于&运算符与比较运算符的优先级,括号也是必需的.的&操作者实际上是具有相同的优先级的算术运算符这反过来又具有比比较运算符的优先级高的重载位运算符.

pandas0.13中,DataFrame.query()将有一种新的实验方法.它与select参数的子集非常类似:

随着query()你会做这样的:

df[['Time', 'Product']].query('Product == p_id and Month < mn and Year == yr')
Run Code Online (Sandbox Code Playgroud)

这是一个简单的例子:

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
Run Code Online (Sandbox Code Playgroud)

您感兴趣的最终查询甚至可以利用链式比较,如下所示:

k1 = df[['Time', 'Product']].query('Product == p_id and start_time <= Time < end_time')
Run Code Online (Sandbox Code Playgroud)


小智 20

只是为了寻找更类似于R的解决方案的人:

df[(df.Product == p_id) & (df.Time> start_time) & (df.Time < end_time)][['Time','Product']]
Run Code Online (Sandbox Code Playgroud)

不需要data.locquery,但我认为它有点长.


小智 12

我发现你可以通过将它包装在[]中来使用给定列的任何子集条件.例如,你有一个带有['Product','Time','Year','Color']列的df

而且假设你想要包括2014年之前制作的产品.你可以写,

df[df['Year'] < 2014]
Run Code Online (Sandbox Code Playgroud)

返回所有行的情况.您可以添加不同的条件.

df[df['Year'] < 2014][df['Color' == 'Red']
Run Code Online (Sandbox Code Playgroud)

然后,只需按照上面的指示选择所需的列.例如,上面df的产品颜色和键,

df[df['Year'] < 2014][df['Color' == 'Red'][['Product','Color']]
Run Code Online (Sandbox Code Playgroud)