Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 根据存在(不存在)早于日期的条目筛选数据框条目_Python_Pandas_Dataframe - Fatal编程技术网

Python 根据存在(不存在)早于日期的条目筛选数据框条目

Python 根据存在(不存在)早于日期的条目筛选数据框条目,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个包含测试运行、日期和结果的DataFrame。看起来是这样的: TestName;Date;IsPassed test1;1/31/2017 9:44:30 PM;0 test1;1/31/2017 9:39:00 PM;0 test1;1/31/2017 9:38:29 PM;1 test1;1/31/2017 9:38:27 PM;1 test2;10/31/2016 5:05:02 AM;0 test3;12/7/2016 8:58:36 PM;0 test3;12/7/2016

我有一个包含测试运行、日期和结果的
DataFrame
。看起来是这样的:

TestName;Date;IsPassed
test1;1/31/2017 9:44:30 PM;0
test1;1/31/2017 9:39:00 PM;0
test1;1/31/2017 9:38:29 PM;1
test1;1/31/2017 9:38:27 PM;1
test2;10/31/2016 5:05:02 AM;0
test3;12/7/2016 8:58:36 PM;0
test3;12/7/2016 8:57:19 PM;0
test3;12/7/2016 8:56:15 PM;0
test4;12/5/2016 6:50:49 PM;0
test4;12/5/2016 6:49:50 PM;0
test4;12/5/2016 3:23:09 AM;1
test4;12/4/2016 11:51:29 PM;1
我希望能够找出在指定日期之前或之后没有运行的测试名称

我当然可以这样说:

TestName;Date;IsPassed
test1;1/31/2017 9:44:30 PM;0
test1;1/31/2017 9:39:00 PM;0
test1;1/31/2017 9:38:29 PM;1
test1;1/31/2017 9:38:27 PM;1
test2;10/31/2016 5:05:02 AM;0
test3;12/7/2016 8:58:36 PM;0
test3;12/7/2016 8:57:19 PM;0
test3;12/7/2016 8:56:15 PM;0
test4;12/5/2016 6:50:49 PM;0
test4;12/5/2016 6:49:50 PM;0
test4;12/5/2016 3:23:09 AM;1
test4;12/4/2016 11:51:29 PM;1
  • 识别所有唯一的测试名称
  • 为每个人计算他们的最小和最大日期
  • 在此基础上,将相应的行添加到新的
    数据帧中
但是,有没有办法在没有显式for循环的情况下,在熊猫身上实现这一点呢

更新

基于@jezrael的解决方案,假设我只想保留2016年的测试运行。那么我必须这样做吗

idx = test_runs.groupby('TestName').Date.agg(['idxmax']).stack().unique()
selected = test_runs.loc[idx].Date < pd.to_datetime('2017-01-01')
tests = test_runs.loc[idx].loc[selected].TestName
print(test_runs[test_runs.TestName.isin(tests)])

我想你需要
groupby
和 对于
index
返回
min
max
日期的值,然后通过将其重塑为
Series
。对于一个
组,如
test2
,也需要删除重复项

最后按以下方式选择所有行:


如果需要排序
索引
添加,因为
唯一
的输出是
numpy数组

print (df.loc[np.sort(idx)])
   TestName                Date  IsPassed
0     test1 2017-01-31 21:44:30         0
3     test1 2017-01-31 21:38:27         1
4     test2 2016-10-31 05:05:02         0
5     test3 2016-12-07 20:58:36         0
7     test3 2016-12-07 20:56:15         0
8     test4 2016-12-05 18:50:49         0
11    test4 2016-12-04 23:51:29         1
编辑:

您的代码看起来不错,只添加了一些改进:

idx = test_runs.groupby('TestName').Date.agg(['idxmin','idxmax']).stack().unique()
#get output to variable, then not need select twice  
df1 = test_runs.loc[idx]
#cast to datetime is not necessary
selected = df1['Date'] < '2017-01-01'
#for selecting in DataFrame is used df[index_val, column_name]
tests = df1.loc[selected, 'TestName']
#for better performance in large df was add unique
print(test_runs[test_runs.TestName.isin(tests.unique())])
   TestName                Date  IsPassed
4     test2 2016-10-31 05:05:02         0
5     test3 2016-12-07 20:58:36         0
6     test3 2016-12-07 20:57:19         0
7     test3 2016-12-07 20:56:15         0
8     test4 2016-12-05 18:50:49         0
9     test4 2016-12-05 18:49:50         0
10    test4 2016-12-05 03:23:09         1
11    test4 2016-12-04 23:51:29         1
idx=test\u runs.groupby('TestName').Date.agg(['idxmin','idxmax']).stack().unique()
#获取变量的输出,然后不需要选择两次
df1=测试运行。loc[idx]
#不需要强制转换到datetime
所选=df1[“日期”]<“2017-01-01”
#用于在数据框中进行选择的是df[索引值,列名称]
tests=df1.loc[选中“TestName”]
#为了在大型df中获得更好的性能,添加了独特的
打印(test_运行[test_运行.TestName.isin(tests.unique())]))
TestName日期已通过
4测试2 2016-10-31 05:05:02 0
5测试3 2016-12-07 20:58:36 0
6测试3 2016-12-07 20:57:19 0
7测试3 2016-12-07 20:56:15 0
8测试4 2016-12-05 18:50:49 0
9测试4 2016-12-05 18:49:50 0
10测试4 2016-12-05 03:23:09 1
11测试4 2016-12-04 23:51:29 1

谢谢!这很接近我所需要的。假设我的任务是只进行2016年11月1日之后的运行(不包括test2)。我必须这样使用吗:
idx=test\u runs.groupby('TestName').Date.agg(['idxmax']).stack().unique()selected=test\u runs.loc[idx].Date>pd.to\u datetime('2016-11-01')tests=test\u runs.loc[idx].loc[selected].TestName打印(tests)]
,但似乎您可以简单地在输出上使用。请检查答案的最后一次编辑。嗯,这有点棘手。在我选择了
之后
我需要返回到原始数据帧,只保留选择的测试名称,但保留所有日期。我会在一分钟内更新问题。编辑答案,请检查。我觉得你的代码很棒。
idx = test_runs.groupby('TestName').Date.agg(['idxmin','idxmax']).stack().unique()
#get output to variable, then not need select twice  
df1 = test_runs.loc[idx]
#cast to datetime is not necessary
selected = df1['Date'] < '2017-01-01'
#for selecting in DataFrame is used df[index_val, column_name]
tests = df1.loc[selected, 'TestName']
#for better performance in large df was add unique
print(test_runs[test_runs.TestName.isin(tests.unique())])
   TestName                Date  IsPassed
4     test2 2016-10-31 05:05:02         0
5     test3 2016-12-07 20:58:36         0
6     test3 2016-12-07 20:57:19         0
7     test3 2016-12-07 20:56:15         0
8     test4 2016-12-05 18:50:49         0
9     test4 2016-12-05 18:49:50         0
10    test4 2016-12-05 03:23:09         1
11    test4 2016-12-04 23:51:29         1