Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/359.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 在特定条件下聚合Dataframe中的行值_Python_Pandas_Dataframe - Fatal编程技术网

Python 在特定条件下聚合Dataframe中的行值

Python 在特定条件下聚合Dataframe中的行值,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个dataframe,它有两列。我想构建所有连续行的总和,其中列0的值为-1 我的dataframe看起来像这样: 0 2 1 3 -1 4 -1 7 0 2 -1 0 -1 1 -1 3 5 0 所需的输出应为: 0 2 1 3 -1 11 0 2 -1 4 5 0 第二列中的值都等于或大于零。如果有帮助,第一列上的值等于或大于-1。我的方法是一个循环,在循环中我创建第二个数据帧,然后将不等于-1的每个值推回

我有一个
dataframe
,它有两列。我想构建所有连续行的总和,其中
列0
的值为
-1

我的
dataframe
看起来像这样:

 0   2
 1   3
-1   4
-1   7
 0   2
-1   0
-1   1
-1   3
 5   0
所需的输出应为:

 0   2
 1   3
-1   11
 0   2
-1   4
 5   0
第二列中的值都等于或大于零。如果有帮助,第一列上的值等于或大于
-1
。我的方法是一个循环,在循环中我创建第二个
数据帧
,然后将不等于
-1
的每个值推回并累积,当我发现一个
-1
时,但我想,这种方法不会有效。 伪代码:

sum = 0
found = False
for row in dataframe:
   if row[0] != -1:
       if found:
           new_df.append([-1, sum])
           sum = 0
           found = False
       new_df.append(row)
   elif row[0] == -1:
       found = True
       sum += row[1]

是否有内置python或pandas函数可用于实现我的目标?

在我看来,如果助手组的值与
-1
之外的值相同,则必须100%确定创建
系列
,因此在
索引中添加
0.5
,以区分:

df = df.reset_index(drop=True)

m = df['a'] == -1
s = m.ne(m.shift()).cumsum()[m].reindex(df.index).fillna(df.index.to_series().add(.5))
df = df.groupby(s).agg({'a':'first', 'b':'sum'}).reset_index(drop=True)
print (df)
   a   b
0  0   2
1  1   3
2 -1  11
3 -1   4
4  0   2
5  5   0
说明

df = pd.DataFrame({'a': [0, 1, -1, -1, 0, -1, -1, -1, 5],
                   'b': [2, 3, 4, 7, 2, 0, 1, 3, 0]})
print (df)
   a  b
0  0  2
1  1  3
2 -1  4
3 -1  7
4  0  2
5 -1  0
6 -1  1
7 -1  3
8  5  0
如有必要,首先创建默认索引,因为在解决方案中使用唯一的索引值:

df = df.reset_index(drop=True)
然后为
-1
和其他值创建连续组:

m = df['a'] == -1
print (df.assign(groups = m.ne(m.shift()).cumsum()))
   a  b  groups
0  0  2       1
1  1  3       1
2 -1  4       2
3 -1  7       2
4  0  2       3
5 -1  0       4
6 -1  1       4
7 -1  3       4
8  5  0       5
然后仅过滤
-1
值(通过掩码
b
),另一个不匹配的值通过以下方式转换为
NaN
s:

然后用
0.5
的索引值替换缺失的值-切勿在
-1
组和替换的
NaN
s组之间合并:

m = df['a'] == -1
print (df.assign(groups = m.ne(m.shift()).cumsum(),
                 filtered = m.ne(m.shift()).cumsum()[m].reindex(df.index),
                 idx = df.index.to_series().add(.5),
                 groups1 = m.ne(m.shift()).cumsum()[m].reindex(df.index).fillna(df.index.to_series().add(.5))))

   a  b  groups  filtered  idx  groups1
0  0  2       1       NaN  0.5      0.5
1  1  3       1       NaN  1.5      1.5
2 -1  4       2       2.0  2.5      2.0
3 -1  7       2       2.0  3.5      2.0
4  0  2       3       NaN  4.5      4.5
5 -1  0       4       4.0  5.5      4.0
6 -1  1       4       4.0  6.5      4.0
7 -1  3       4       4.0  7.5      4.0
8  5  0       5       NaN  8.5      8.5
然后将helper
Series
传递给
groupby
,并将第二列的
sum
和第一列的
first
进行聚合,最后一列通过
drop=True删除索引:

df = df.groupby(s).agg({'a':'first', 'b':'sum'}).reset_index(drop=True)
print (df)
   a   b
0  0   2
1  1   3
2 -1  11
3 -1   4
4  0   2
5  5   0

另一种更简单、性能更好的解决方案:

df = df.reset_index(drop=True)

m = df['a'] == -1
s = df.reset_index()
      .groupby(m.ne(m.shift()).cumsum()[m])
      .agg({'index':'first', 'b':'sum'})
      .set_index('index')
      .assign(a = -1)

df = df[~m].append(s, sort=True).sort_index()
print (df)
   a   b
0  0   2
1  1   3
2 -1  11
4  0   2
5 -1   4
8  5   0
说明

df = pd.DataFrame({'a': [0, 1, -1, -1, 0, -1, -1, -1, 5],
                   'b': [2, 3, 4, 7, 2, 0, 1, 3, 0]})
print (df)
   a  b
0  0  2
1  1  3
2 -1  4
3 -1  7
4  0  2
5 -1  0
6 -1  1
7 -1  3
8  5  0
首先是必要的默认索引:

df = df.reset_index(drop=True)
然后将
-1
列与布尔掩码进行比较:

m = df['a'] == -1
通过
reset_index
将索引转换为列,无
drop
参数:

print (df.reset_index())
   index  a  b
0      0  0  2
1      1  1  3
2      2 -1  4
3      3 -1  7
4      4  0  2
5      5 -1  0
6      6 -1  1
7      7 -1  3
8      8  5  0
使用
shift
cumsum
创建连续组,并按掩码为
-1
组进行筛选:

print (m.ne(m.shift()).cumsum()[m])
2    2
3    2
5    4
6    4
7    4
Name: a, dtype: int32
按索引列聚合
first
,按
b
列聚合
sum

print (df.reset_index()
        .groupby(m.ne(m.shift()).cumsum()[m])
        .agg({'index':'first', 'b':'sum'}))

     index   b
a             
2.0      2  11
4.0      5   4
通过以下方式将
索引
列转换为
索引

通过以下方式添加具有常量
-1
列:

最后一次过滤出
-1
行,使用反向掩码按
~

print (df[~m])
  a  b
0  0  2
1  1  3
4  0  2
8  5  0
然后通过以下方式将新数据添加到原始数据:

最后,对于相同的订购:

print (df[~m].append(s, sort=True).sort_index())
   a   b
0  0   2
1  1   3
2 -1  11
4  0   2
5 -1   4
8  5   0

你能详细地告诉我每一行发生了什么吗?我是python新手,但我想确定,我正确地、以最佳方式使用了pythonpossible@RoQuOTriX-添加解释,使用
-1
解决第一个值的任何值。
print (df[~m])
  a  b
0  0  2
1  1  3
4  0  2
8  5  0
print (df[~m].append(s, sort=True))
   a   b
0  0   2
1  1   3
4  0   2
8  5   0
2 -1  11
5 -1   4
print (df[~m].append(s, sort=True).sort_index())
   a   b
0  0   2
1  1   3
2 -1  11
4  0   2
5 -1   4
8  5   0