2017-09-23 85 views
0
import pandas as pd 

data = {'date': ['1998-03-01', '2001-04-01','1998-06-01','2001-08-01','2001-05-03'], 
    'node1': [1, 1, 2,2,3], 
'node2': [8,316,26,35,44], 
'weight': [1,1,1,1,1], } 
df = pd.DataFrame(data, columns = ['date', 'node1','node2','weight']) 
print(df) 

mask1 = (df['date'] > '1998-01-01 00:00:01') & (df['date'] <= '2000-01-01 
00:00:01') 
mask2 = (df['date'] > '2000-01-01 00:00:01') & (df['date'] <= '2003-01-01 
00:00:01') 

mask = pd.concat((mask1, mask2), axis=1) 
slct = mask.all(axis=1) 
print df.ix[slct] 

以上是我的尝试。数据集(以上是玩具数据集)有4列,即node1,node2,weight,timestamp。我想创建两组具有以下条件的行:set1应该包含时间戳在98-00年和2年00-02之间的行。以熊猫中两个时间戳范围条件的交集

同样,两组都应该在两个年份范围(98-00和00-02)中的行。

所以在上面的例子中,两个集合应该是{1,2}和{1,2} .3应该被排除,因为它只出现在00-02范围内。 但我在答案中得到空框架。 首先,我做了mask1和mask2以获得满足各个范围的行,然后将它们连接在一起以找到两个条件的交集。

+0

你期望输出是什么? – Dark

+0

在上面的例子中,答案应该是node:{1,1,2,2}。只有node1:{3}应该被排除。 –

+0

为什么排除3年是2001年? – Dark

回答

1

你可以使用groupby与isin来知道日期包含1998-2000和2000-2002,即使用掩码基于node1的groupby这

df['date'] = pd.to_datetime(df['date']) 
mask = df.groupby('node1').apply(lambda x : (x['date'].dt.year.isin([1998,1999,2000])).any()) 
mask2 = df.groupby('node1').apply(lambda x : (x['date'].dt.year.isin([2000,2001,2002])).any()) 

df[df['node1'].isin(mask[mask & mask2].index)] # Get the dataframe 

说明

maskmask2将使得像

 
mask     mask2 
(node1     node1 
1  True   1 True 
2  True   2 True 
3 False   3 True 
dtype: bool,  dtype: bool) 
面具

后来我们就可以使用&基于真值表拿到面具,一个新的面具,只有真正的值,即

mask[mask & mask2] 
 
node1 
1 True 
2 True 
dtype: bool 

选择基于新的面具即

df['node1'].isin(mask[mask & mask2].index) 
 
0  True 
1  True 
2  True 
3  True 
4 False 
Name: node1, dtype: bool 
的DF

输出:

df[df['node1'].isin(mask[mask & mask2].index)] 
 
     date node1 node2 weight 
0 1998-03-01  1  8  1 
1 2001-04-01  1 316  1 
2 1998-06-01  2  26  1 
3 2001-08-01  2  35  1 
+0

我觉得我不明白“使用后会给面具”一步。你能解释一下吗?谢谢 –

+0

此错误显示:AttributeError:只能使用.dt访问器与datetimelike值 –

+0

我认为你的日期列在标准的日期时间dtype。所以你需要使用'pd.to_datetime'。 – Dark

1

这里有两个问题。首先mask1和mask2只给你布尔值。您需要使用这2个布尔值来为您的数据帧建立索引。

其次,你的pd.concat需要一个迭代器作为参数,并且你已经提供了对象。

检查了这一点

data = { 'node1': [1, 1, 2,2,3], 'node2': [8,316,26,35,44], 'weight': [1,1,1,1,1], 'date' : 
     ['1998-03-01', '2001-04-01','1998-06-01','2001-08-01','2001-05-03'] } 
df = pd.DataFrame(data) 
mask1 = df.loc[(df['date'] > '1998-01-01 00:00:01') & (df['date'] <= '2000-01-01 00:00:01'), :] 
mask2 = df.loc[(df['date'] > '2000-01-01 00:00:01') & (df['date'] <= '2003-01-01 00:00:01'), :] 
pd.concat([mask1, mask2], axis = 0) 

我仍然不知道你究竟是如何想你的输出。此外,我会建议停止使用.ix和开始习惯使用.loc和.iloc

+0

在上述情况下,答案应该是节点:{1,1,2,2}。只有node1:{3}应该被排除,因为节点3只出现在范围00-02中,而不是出现在98-00中其他出现在98-00和00-02两个年份。 –