【问题标题】:Taking the intersection of two timestamp range conditions in pandas在 pandas 中取两个时间戳范围条件的交集
【发布时间】:2018-03-04 20:28:03
【问题描述】:
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 以获得满足各个范围的行,然后我将它们连接起来以找到两个条件的交集。

【问题讨论】:

  • 你期望输出是什么?
  • 在上述情况下,答案应为节点:{1,1,2,2}。应仅排除节点 1:{3}。
  • 为什么排除 3 年份是 2001 na?
  • 因为我需要98-00和00-02都出现过的节点。 3 仅在 00-02 范围内。
  • 我明白了这个问题,现在请检查我的解决方案。

标签: python python-2.7 pandas dataframe


【解决方案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 会给出类似

的掩码 面具面具2 (节点 1 节点 1 1 正确 1 正确 2 真 2 真 3 假 3 真 数据类型:布尔,数据类型:布尔)

稍后我们可以使用&amp;根据真值表得到掩码,一个只有真值的新掩码,即

mask[mask & mask2] 
节点1 1 对 2 真 数据类型:布尔

根据新掩码选择df,即

df['node1'].isin(mask[mask & mask2].index)
0 真 1 对 2 真 3 真 4 错误 名称:node1,数据类型:bool

输出:

df[df['node1'].isin(mask[mask & mask2].index)]
日期节点1节点2权重 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

【讨论】:

  • 我想我没看懂“使用后&会给面具”这一步。你能解释一下吗?谢谢
  • 显示此错误:AttributeError: Can only use .dt accessor with datetimelike values
  • 我认为您的日期列是标准的 datetime dtype。所以你需要使用pd.to_datetime
  • 不要忘记现在就接受答案,并在获得足够声誉时投票。祝你有美好的一天
  • 这一步掩码[掩码和掩码2]。这不应该是掩码[掩码1和掩码2]吗?两个掩码(掩码 1 和掩码 2)的 & 应该存储在一个新的变量掩码中。
【解决方案2】:

这里有2个问题。首先 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

【讨论】:

  • 在上述情况下,答案应该是节点:{1,1,2,2}。只有节点 1:{3} 应该被排除,因为节点 3 只出现在 00- 范围内02 而不是在 98-00。其他都出现在 98-00 和 00-02 的年份范围内。
猜你喜欢
  • 1970-01-01
  • 2013-10-07
  • 1970-01-01
  • 2014-07-04
  • 2020-11-26
  • 1970-01-01
  • 2014-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多