Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/291.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.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 - Fatal编程技术网

Python 基于条件迭代数据帧中行子集的最快方法

Python 基于条件迭代数据帧中行子集的最快方法,python,pandas,Python,Pandas,我有一个带有一列ID和一列值的数据框——每个ID与两行或更多行相关联。当给定ID中的任何值子集满足我的条件(在本例中,值子集等于零)时,我希望使用新ID标记这些行,新ID由原始ID和附加编号组成,以唯一标识这些子集 到目前为止我已经尝试过的代码: import pandas as pd d = {'ID': ['2016/01 100','2016/01 100','2016/01 100','2016/01 100','2016/01 200',\ '2016/01 200','2016/0

我有一个带有一列ID和一列值的数据框——每个ID与两行或更多行相关联。当给定ID中的任何值子集满足我的条件(在本例中,值子集等于零)时,我希望使用新ID标记这些行,新ID由原始ID和附加编号组成,以唯一标识这些子集

到目前为止我已经尝试过的代码:

import pandas as pd

d = {'ID': ['2016/01 100','2016/01 100','2016/01 100','2016/01 100','2016/01 200',\
'2016/01 200','2016/01 200','2016/01 200'], 'Value': [-343.68, 343.68, -55.2, 55.2,\
-158.77, 158.77, 123.3, -123.3]}

df = pd.DataFrame(data=d)

df['Cumulative_Sum'] = round(df.Value.cumsum(),2)

print(df)

current_ID = df.loc[0, 'ID']
sum_counter = 1
counter = 0
for row in df.index.values:
    if (df.loc[row, 'Cumulative_Sum'] == 0):
        df.loc[counter:row, 'New_ID'] = str(df.loc[row, 'ID']) + "_" + str(sum_counter)
        counter = row + 1
        sum_counter = sum_counter + 1
        if (counter < len(df.index.values)):    
            if (df.loc[counter, 'ID'] != df.loc[row, 'ID']):
                sum_counter = 1

print (df)

有没有一种更快的方法可以在不循环的情况下做到这一点,同时保持新ID的格式符合我的需要?

对于这种令人讨厌的外观,我深表歉意

我使用嵌套调用对group by where with in进行分组,我使用
cumsum
查找以零结尾的连续组。最后,使用
ngroup
获取标签

然后我使用
pd.Series.str.cat
将结果附加到旧ID

df.assign(
    New_ID=
    df.ID.str.cat(
        df.groupby('ID').apply(
            lambda d: d.groupby(
                d.Cumulative_Sum.eq(0).iloc[::-1].cumsum(),
                sort=False).ngroup()
        ).add(1).astype(str),
        sep='_'
    )
)

            ID   Value  Cumulative_Sum         New_ID
0  2016/01 100 -343.68         -343.68  2016/01 100_1
1  2016/01 100  343.68            0.00  2016/01 100_1
2  2016/01 100  -55.20          -55.20  2016/01 100_2
3  2016/01 100   55.20            0.00  2016/01 100_2
4  2016/01 200 -158.77         -158.77  2016/01 200_1
5  2016/01 200  158.77            0.00  2016/01 200_1
6  2016/01 200  123.30          123.30  2016/01 200_2
7  2016/01 200 -123.30            0.00  2016/01 200_2

尝试运行此操作时出错-AttributeError:“DataFrameGroupBy”对象没有属性“ngroup”。“知道我做错了什么吗?”大卫可能是熊猫的老版本。我不再在电脑前测试了。你说得对,我把它修好了。这将我在测试数据集上的运行时间从20分钟减少到了2分钟。谢谢
df.assign(
    New_ID=
    df.ID.str.cat(
        df.groupby('ID').apply(
            lambda d: d.groupby(
                d.Cumulative_Sum.eq(0).iloc[::-1].cumsum(),
                sort=False).ngroup()
        ).add(1).astype(str),
        sep='_'
    )
)

            ID   Value  Cumulative_Sum         New_ID
0  2016/01 100 -343.68         -343.68  2016/01 100_1
1  2016/01 100  343.68            0.00  2016/01 100_1
2  2016/01 100  -55.20          -55.20  2016/01 100_2
3  2016/01 100   55.20            0.00  2016/01 100_2
4  2016/01 200 -158.77         -158.77  2016/01 200_1
5  2016/01 200  158.77            0.00  2016/01 200_1
6  2016/01 200  123.30          123.30  2016/01 200_2
7  2016/01 200 -123.30            0.00  2016/01 200_2