Pandas 如何获取数据框中所有非零值范围的第一个和最后一个日期?
Pandas how to get the first and last dates of all non-zero value ranges in a data frame?
我有一个如下所示的数据框:
df = pd.DataFrame({"A":[10,0,30,40,0,60,70,80,90]}, index = pd.date_range(start='1/1/2020', end='1/09/2020'))
df
A
2020-01-01 10
2020-01-02 0
2020-01-03 30
2020-01-04 40
2020-01-05 0
2020-01-06 60
2020-01-07 70
2020-01-08 80
2020-01-09 90
我想遍历数据框以获取 t0
和 t1
,它们分别代表 [ 的每个非零值范围的第一个和最后一个日期(即索引值) =14=].
在上面的 table 中,我想为 t0
和 t1
获取以下值:
t0 = 2020-01-01
, t1 = 2020-01-01
t0 = 2020-01-03
, t1 = 2020-01-04
t0 = 2020-01-06
, t1 = 2020-01-09
在 Pandas 中有没有简单的方法来做到这一点?
一种选择是根据 A=0 的位置创建布尔索引。然后 groupby
cumsum
of that Index and aggregate
first
和 last
日期(假设索引按此处排序):
new_df = df.reset_index()
m = new_df['A'].eq(0)
new_df = (
new_df.groupby(m.cumsum()[~m])
.agg(t0=('index', 'first'), t1=('index', 'last'))
.reset_index(drop=True)
)
t0 t1
0 2020-01-01 2020-01-01
1 2020-01-03 2020-01-04
2 2020-01-06 2020-01-09
获取 min
和 max
索引值而不是 first
和 last
的替代方法:
new_df = df.reset_index()
m = new_df['A'].eq(0)
new_df = (
new_df.groupby(m.cumsum()[~m])
.agg(t0=('index', 'min'), t1=('index', 'max'))
.reset_index(drop=True)
)
t0 t1
0 2020-01-01 2020-01-01
1 2020-01-03 2020-01-04
2 2020-01-06 2020-01-09
索引:
m
:
0 False
1 True
2 False
3 False
4 True
5 False
6 False
7 False
8 False
Name: A, dtype: bool
创建由 0 分隔的组:
m.cumsum()
0 0
1 1
2 1
3 1
4 2
5 2
6 2
7 2
8 2
Name: A, dtype: int32
自我过滤以排除 0 行:
m.cumsum()[~m]
0 0
2 1
3 1
5 2
6 2
7 2
8 2
Name: A, dtype: int32
然后将这些行组合在一起以确定关联的日期。
您可以使用 groupby
和 agg
同时查找每个范围的第一个日期和最后一个日期。
试试这个:
df = df.reset_index().groupby('A').agg({'first','last'})
df.columns = df.columns.droplevel(0)
print(df)
输出:
first last
A
0 2020-01-02 2020-01-05
10 2020-01-01 2020-01-01
30 2020-01-03 2020-01-03
40 2020-01-04 2020-01-04
60 2020-01-06 2020-01-06
70 2020-01-07 2020-01-07
80 2020-01-08 2020-01-08
90 2020-01-09 2020-01-09
我有一个如下所示的数据框:
df = pd.DataFrame({"A":[10,0,30,40,0,60,70,80,90]}, index = pd.date_range(start='1/1/2020', end='1/09/2020'))
df
A
2020-01-01 10
2020-01-02 0
2020-01-03 30
2020-01-04 40
2020-01-05 0
2020-01-06 60
2020-01-07 70
2020-01-08 80
2020-01-09 90
我想遍历数据框以获取 t0
和 t1
,它们分别代表 [ 的每个非零值范围的第一个和最后一个日期(即索引值) =14=].
在上面的 table 中,我想为 t0
和 t1
获取以下值:
t0 = 2020-01-01
, t1 = 2020-01-01
t0 = 2020-01-03
, t1 = 2020-01-04
t0 = 2020-01-06
, t1 = 2020-01-09
在 Pandas 中有没有简单的方法来做到这一点?
一种选择是根据 A=0 的位置创建布尔索引。然后 groupby
cumsum
of that Index and aggregate
first
和 last
日期(假设索引按此处排序):
new_df = df.reset_index()
m = new_df['A'].eq(0)
new_df = (
new_df.groupby(m.cumsum()[~m])
.agg(t0=('index', 'first'), t1=('index', 'last'))
.reset_index(drop=True)
)
t0 t1
0 2020-01-01 2020-01-01
1 2020-01-03 2020-01-04
2 2020-01-06 2020-01-09
获取 min
和 max
索引值而不是 first
和 last
的替代方法:
new_df = df.reset_index()
m = new_df['A'].eq(0)
new_df = (
new_df.groupby(m.cumsum()[~m])
.agg(t0=('index', 'min'), t1=('index', 'max'))
.reset_index(drop=True)
)
t0 t1
0 2020-01-01 2020-01-01
1 2020-01-03 2020-01-04
2 2020-01-06 2020-01-09
索引:
m
:
0 False
1 True
2 False
3 False
4 True
5 False
6 False
7 False
8 False
Name: A, dtype: bool
创建由 0 分隔的组:
m.cumsum()
0 0
1 1
2 1
3 1
4 2
5 2
6 2
7 2
8 2
Name: A, dtype: int32
自我过滤以排除 0 行:
m.cumsum()[~m]
0 0
2 1
3 1
5 2
6 2
7 2
8 2
Name: A, dtype: int32
然后将这些行组合在一起以确定关联的日期。
您可以使用 groupby
和 agg
同时查找每个范围的第一个日期和最后一个日期。
试试这个:
df = df.reset_index().groupby('A').agg({'first','last'})
df.columns = df.columns.droplevel(0)
print(df)
输出:
first last
A
0 2020-01-02 2020-01-05
10 2020-01-01 2020-01-01
30 2020-01-03 2020-01-03
40 2020-01-04 2020-01-04
60 2020-01-06 2020-01-06
70 2020-01-07 2020-01-07
80 2020-01-08 2020-01-08
90 2020-01-09 2020-01-09