>我有一个结果集,我想从中获取与特定单元格值匹配的行之后(之前)的下 n 行(或前 n 行)。
例如,这是我的数据:
A B C
1 10 2018-11-01
2 20 2018-10-31
3 30 2018-10-30
4 40 2018-10-29
5 50 2018-10-28
6 60 2018-10-27
我有兴趣在 C=2018-10-28(日期类型)的行之前获得 3 行,包括 C=2018-10-28 行,所以我的输出应该是
A B C
3 30 2018-10-30
4 40 2018-10-29
5 50 2018-10-28
我尝试了 loc,但它需要索引,所以这引发了错误:df2 = df2.loc[:C].tail(3)
TypeError: can't compare datetime.date to int
。
检查dtypes
df
: 如果C
列中的df.dtypes
不是日期时间,则将其转换为日期时间:
df.dtypes
Out[46]:
B int64
C object
dtype: object
df['C'] = pd.to_datetime(df['C'])
df.dtypes
Out[48]:
B int64
C datetime64[ns]
dtype: object
现在,"C"列与日期时间格式的字符串相当:
target_date = "2018-10-28"
df[df['C'] >= target_date].tail(3)
B C
A
3 30 2018-10-30
4 40 2018-10-29
5 50 2018-10-28
但在更一般的情况下(有多个目标列并且数据是无序的),您可以使用以下方法:
df
A B C
0 10 2018-09-10
1 20 2018-07-11
2 20 2018-06-12
3 30 2018-07-13
4 50 2018-10-28
5 10 2018-11-01
6 20 2018-10-31
7 30 2018-10-30
8 40 2018-10-29
9 50 2018-10-28
10 60 2018-10-27
index = df[df['C'] == '2018-10-28'].index
index
Out:
Int64Index([4, 9], dtype='int64', name=0)
使用 slice
和 .iloc
获取目标:
slices = [slice(i, i-3, -1) for i in indicies]
slices
Out: [slice(4, 1, -1), slice(9, 6, -1)]
pd.concat([df.iloc[sl] for sl in slices])
B C
A
4 50 2018-10-28
3 30 2018-07-13
2 20 2018-06-12
9 50 2018-10-28
8 40 2018-10-29
7 30 2018-10-30
生成的帧未排序,但很容易修复。此方法仅适用于数字索引,但在不存在的情况下,您可以使用 pd.reset_index()
添加它。
我有兴趣在 C = 2018-10-28 的行之前获得 3 行
首先通过pd.Series.idxmax
找到索引,然后使用pd.DataFrame.iloc
切片,它支持整数位置索引:
idx = df['C'].eq('2018-10-28').idxmax()
res = df.iloc[idx-2: idx+1]
print(res)
# A B C
# 2 3 30 2018-10-30
# 3 4 40 2018-10-29
# 4 5 50 2018-10-28
你可以使用一些东西
s = StringIO("""
A B C
1 10 2018-11-01
2 20 2018-10-31
3 30 2018-10-30
4 40 2018-10-29
5 50 2018-10-28
6 60 2018-10-27""")
final = pd.read_csv(s, sep='ss+', engine='python')
final['C] = pd.to_datetime(final['C])
最后
A B C
0 1 10 2018-11-01
1 2 20 2018-10-31
2 3 30 2018-10-30
3 4 40 2018-10-29
4 5 50 2018-10-28
5 6 60 2018-10-27
final.loc[final[final['C'] == '2018-10-28'].index[0]-2:final[final['C'] == '2018-10-28' ].index[0]]
输出
A B C
2 3 30 2018-10-30
3 4 40 2018-10-29
4 5 50 2018-10-28