通过 Pandas 系列中的多个实例计算第一个非零值和最后一个非零值之间的差异?
Calculate difference between first non-zero value and last non-zero value through multiple instances in Pandas Series?
我有一个 DataFrame,列 col_c 值为 0,正整数 0,负整数 0。我想 return 一个新列(col_d 如下所示) 的值计算第一个非零值和最后一个非零值之间的差值。原始 DataFrame 演示了 col_c 个值:
col_a col_b col_c
1 AB 0 0
2 AB 0 0
3 AB 1 1
4 AB 1 2
5 AB 1 5
6 AB 1 3
7 AB 0 0
8 AB 0 0
9 AB -1 -1
10 AB -1 -2
11 AB -1 -5
12 AB -1 -3
13 AB 0 0
14 AB 0 0
我想 return 如下所示的 DataFrame,其中第 6 行和第 12 行中的值 2 根据 col_c 计算为 (3-1) = 2 和 (-3 - -1 ) = -2:
col_a col_b col_c col_d
1 AB 0 0 0
2 AB 0 0 0
3 AB 1 1 0
4 AB 1 2 0
5 AB 1 5 0
6 AB 1 3 2
7 AB 0 0 0
8 AB 0 0 0
9 AB -1 -1 0
10 AB -1 -2 0
11 AB -1 -5 0
12 AB -1 -3 2
13 AB 0 0 0
14 AB 0 0 0
这是使用循环的另一种方式:
df['col_d'] = 0
count = 0
for row in range(0, len(df)-1):
if df['col_c'][count] != 0 and df['col_c'][count+1] == 0:
df['col_d'][count] = df['col_c'][count] - df['col_b'][count]
count += 1
首先,创建 d 列并将所有行都设置为 0。然后,循环遍历数据框并查找以下行:
- c 列不等于 0
- 在下一行中,c 列确实等于 0
然后将该行的 d 列设置为:c 列减去 b 列。
高级别
- 找到零点:
df.col_c.eq(0)
- 使用
cumsum
创建群组
- 用
-1
替换实际的零位置,因为它是我关心的非零
- 执行
groupby
和 agg
'last'
小组垫底
'first'
获得小组第一
'last_valid_index
想办法把它放在哪里
- 删除
-1
组,因为那些是我不关心的零
- 使用
last_valid_index
的结果创建一个字典,值是 'last'
和 'first'
之间的差异
- 使用
assign
和 index.map
创建新列
index.map
需要调用,所以我使用 dict.get
方法。但是,我们希望默认为零,以便 dict.get
可以采用默认值。
m = df.col_c.eq(0)
g = m.cumsum().mask(m, -1)
d = df.col_c.groupby(g).agg(['last', 'first', lambda x: x.last_valid_index()]).drop(-1)
k = dict(zip(d['<lambda>'], d['last'] - d['first']))
df.assign(col_d=df.index.map(lambda x: k.get(x, 0)))
col_a col_b col_c col_d
1 AB 0 0 0
2 AB 0 0 0
3 AB 1 1 0
4 AB 1 2 0
5 AB 1 5 0
6 AB 1 3 2
7 AB 0 0 0
8 AB 0 0 0
9 AB -1 -1 0
10 AB -1 -2 0
11 AB -1 -5 0
12 AB -1 -3 -2
13 AB 0 0 0
14 AB 0 0 0
您似乎在计算最后两列之间的绝对差值,无论值是 0 还是非零。如果是这种情况,您可以这样做:
df['new'] = df.iloc[:,[-2,-1]].apply(lambda (x,y):abs(x-y), axis=1)
我有一个 DataFrame,列 col_c 值为 0,正整数 0,负整数 0。我想 return 一个新列(col_d 如下所示) 的值计算第一个非零值和最后一个非零值之间的差值。原始 DataFrame 演示了 col_c 个值:
col_a col_b col_c
1 AB 0 0
2 AB 0 0
3 AB 1 1
4 AB 1 2
5 AB 1 5
6 AB 1 3
7 AB 0 0
8 AB 0 0
9 AB -1 -1
10 AB -1 -2
11 AB -1 -5
12 AB -1 -3
13 AB 0 0
14 AB 0 0
我想 return 如下所示的 DataFrame,其中第 6 行和第 12 行中的值 2 根据 col_c 计算为 (3-1) = 2 和 (-3 - -1 ) = -2:
col_a col_b col_c col_d
1 AB 0 0 0
2 AB 0 0 0
3 AB 1 1 0
4 AB 1 2 0
5 AB 1 5 0
6 AB 1 3 2
7 AB 0 0 0
8 AB 0 0 0
9 AB -1 -1 0
10 AB -1 -2 0
11 AB -1 -5 0
12 AB -1 -3 2
13 AB 0 0 0
14 AB 0 0 0
这是使用循环的另一种方式:
df['col_d'] = 0
count = 0
for row in range(0, len(df)-1):
if df['col_c'][count] != 0 and df['col_c'][count+1] == 0:
df['col_d'][count] = df['col_c'][count] - df['col_b'][count]
count += 1
首先,创建 d 列并将所有行都设置为 0。然后,循环遍历数据框并查找以下行:
- c 列不等于 0
- 在下一行中,c 列确实等于 0
然后将该行的 d 列设置为:c 列减去 b 列。
高级别
- 找到零点:
df.col_c.eq(0)
- 使用
cumsum
创建群组 - 用
-1
替换实际的零位置,因为它是我关心的非零 - 执行
groupby
和agg
'last'
小组垫底'first'
获得小组第一'last_valid_index
想办法把它放在哪里- 删除
-1
组,因为那些是我不关心的零
- 使用
last_valid_index
的结果创建一个字典,值是'last'
和'first'
之间的差异
- 使用
assign
和index.map
创建新列index.map
需要调用,所以我使用dict.get
方法。但是,我们希望默认为零,以便dict.get
可以采用默认值。
m = df.col_c.eq(0)
g = m.cumsum().mask(m, -1)
d = df.col_c.groupby(g).agg(['last', 'first', lambda x: x.last_valid_index()]).drop(-1)
k = dict(zip(d['<lambda>'], d['last'] - d['first']))
df.assign(col_d=df.index.map(lambda x: k.get(x, 0)))
col_a col_b col_c col_d
1 AB 0 0 0
2 AB 0 0 0
3 AB 1 1 0
4 AB 1 2 0
5 AB 1 5 0
6 AB 1 3 2
7 AB 0 0 0
8 AB 0 0 0
9 AB -1 -1 0
10 AB -1 -2 0
11 AB -1 -5 0
12 AB -1 -3 -2
13 AB 0 0 0
14 AB 0 0 0
您似乎在计算最后两列之间的绝对差值,无论值是 0 还是非零。如果是这种情况,您可以这样做:
df['new'] = df.iloc[:,[-2,-1]].apply(lambda (x,y):abs(x-y), axis=1)