Python 作为熊猫中Groupby的一部分,将日期范围隐藏到Numpy数组

Python 作为熊猫中Groupby的一部分,将日期范围隐藏到Numpy数组,python,arrays,python-2.7,pandas,numpy,Python,Arrays,Python 2.7,Pandas,Numpy,我从一个有三列的数据库中查询了一个Pandasdataframe。开始日期、结束日期和人员。这些数据可能没有多大意义,但只是一个简化的例子 startdate enddate person 0 2016-01-01 2016-01-02 A 1 2016-01-03 2016-01-03 A 2 2016-01-01 2016-01-01 B 3 2016-01-02 2016-01-02 B 在给定的日期范围内,我想知道

我从一个有三列的数据库中查询了一个
Pandas
dataframe
。开始日期、结束日期和人员。这些数据可能没有多大意义,但只是一个简化的例子

    startdate     enddate person
0  2016-01-01  2016-01-02      A
1  2016-01-03  2016-01-03      A
2  2016-01-01  2016-01-01      B
3  2016-01-02  2016-01-02      B
在给定的日期范围内,我想知道我的
dataframe
中每个人的条目所涵盖的日期。我的想法是创建一个长度等于范围内天数的
numpy
数组。如果该特定日期在该范围内,则数组中该索引的值设置为1,否则为0。然后,我可以使用
groupby
lambda
函数进行展平

因此,考虑到上述数据框架,以及从
2016-01-01
2016-01-03
的日期范围,最终结果将是:

       date_binary
person            
A        [1, 1, 1]
B        [1, 1, 0]
我已经能够计算出一些代码(groupby的
部分),但不确定如何从日期范围转换为数组。所以在下面的完整示例中,我只是硬编码了转换后的数据帧。我想,我本可以在有问题的部分周围问一个更简单的问题,但我知道使用
Pandas
通常有一种非常简洁的方法来做事情,所以我甚至发布了工作部分

import pandas as pd
from datetime import datetime
import numpy as np
# initial dataset
df = pd.DataFrame(data=[['2016-01-01', '2016-01-02', 'A'],
                        ['2016-01-03', '2016-01-03', 'A'],
                        ['2016-01-01', '2016-01-01', 'B'],
                        ['2016-01-02', '2016-01-02', 'B']],
                  columns=['startdate', 'enddate', 'person'])

# convert columns to dates
df['startdate']= pd.to_datetime(df['startdate'],  format='%Y-%m-%d')
df['enddate']= pd.to_datetime(df['enddate'],  format='%Y-%m-%d')

# define period for which the matrix should be created
start_date = datetime(month=01, day=1, year=2016)
end_date = datetime(month=1, day=10, year=2016)


######################
# Unsure how to do this 
#####################

# what the dataframe should look like
df = pd.DataFrame(data=[[[1, 1, 0], 'A'],
                         [[0, 0, 1], 'A'],
                         [[1, 0, 0], 'B'],
                         [[0, 1, 0], 'B']],
                  columns=['date_binary', 'person'])

# flatten by person
df = df.groupby('person').aggregate(lambda x: tuple(x))

# take the max value
df.date_binary = df.date_binary.apply(lambda x: np.array([max(i) for i in zip(*x)]))

print df
我认为您可以通过返回
new\u index
indexer
来定制函数。最后需要将
索引器中的值
-1
替换为
0
,将另一个值替换为
1


谢谢,这是一个很好的解决方案。你能解释一下(arr==-1,0,1)
在做什么吗?如果条件为真,则其中很简单,否则为0。这里索引器返回
-1
如果缺少值-您需要
0
,对于另一个值,当我打印
arr
时需要
1
,数组的第一行是
[0 1-1]
。因为这对应于
['2016-01-01','2016-01-02','A']
,所以它不应该是
[1,1,-1]
,因为我们有两个匹配项,然后超出范围一天吗?也许我不理解那个代码在做什么。我理解它
-1
意味着缺少值,如果
0
1
2
它是第一个数组的值索引
# define period for which the matrix should be created
start_date = datetime(month=1, day=1, year=2016)
end_date = datetime(month=1, day=3, year=2016)

dr = pd.date_range(start_date, end_date) 

def f(x):
    arr = pd.date_range(x.startdate, x.enddate).reindex(dr)[1]
    return pd.Series([np.where(arr == -1, 0, 1)])

df['date_binary'] = df.apply(f, axis=1)
df = df[['date_binary', 'person']]
print (df)
  date_binary person
0   [1, 1, 0]      A
1   [0, 0, 1]      A
2   [1, 0, 0]      B
3   [0, 1, 0]      B