pandas Python panda使用基于布尔行的字符串代码创建新列

amrnrhlw  于 2023-02-02  发布在  Python
关注(0)|答案(2)|浏览(119)

我有一个 Dataframe ,其中包含多列布尔值/整数(1/0)。我需要一个新的结果Pandas列,其中包含由以下代码构建的字符串:如果链被中断,则True连续出现多少次,以及True从哪列到哪列。
例如,这是以下 Dataframe :

column_1  column_2  column_3  column_4  column_5  column_6  column_7  column_8  column_9  column_10 
0          0         1         0         1         1         1         1         0         0          1
1          0         1         1         0         1         1         1         0         0          1
2          1         1         0         0         0         1         1         0         0          1
3          1         1         1         0         0         0         0         1         1          1
4          1         1         1         0         0         1         0         0         1          1
5          1         1         1         0         0         0         1         1         0          1
6          0         1         1         1         1         1         1         0         1          0

其中以下列为例:1:[0 1 1 0 1 1 0 0 1]
将在column_result中生成代码字符串:* * i2/2 - 3/c2-c3_c5-c7/6**它是由四个部分构建的,我可以在稍后的代码中阅读。
第一部分:

  • 其中"i"代表中断,如果没有中断,则"c"代表连续
  • 2表示它找到2个或更多连续True的次数,

第二部分:

  • 连续组的连续计数,在这种情况下第一连续计数是2,第二计数是3。

第3阶段:

  • 找到第一个True的列的编号/ID以及找到连续True的最后一个True的列编号。

第4阶段:

  • 仅为行中True的总数。

另一个示例是下面的行:6:[0 1 1 1 1 1 1 0 1 0]将在column_result中生成代码字符串:* * c1/6/c2-c7/7号文件**
下面的代码是我用来创建上面的datafame的起始代码,其中的bool是随机整数:

def create_custom_result(df: pd.DataFrame) -> pd.Series:
    return df

def create_dataframe() -> pd.DataFrame:
    df = pd.DataFrame()  # empty df

    for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:   # create random bool/int values
        df[f'column_{i}'] = np.random.randint(2, size=50)

    df["column_result"] = ''    # add result column
    return df

if __name__=="__main__":

    df = create_dataframe()
    custom_results = create_custom_result(df=df)

有人知道如何解决这个问题吗?老实说,我不知道从哪里开始。我发现以下可能是最接近的:count sets of consecutive true values in a column,但是,它使用列而不是行水平。也许有人可以告诉我,如果我应该尝试np. array的东西,或者也许panda有一些函数可以帮助我?我发现一些groupby函数可以水平工作,但是我不知道如何将其转换为结果列中使用的字符串代码,或者我应该按行循环 Dataframe ,然后构建列_结果代码在段中?
先谢了!
我已经尝试了一些方法,逐行循环 Dataframe ,但是不知道如何用代码字符串构建一个新列。
我还发现这篇文章:pandas groupby ..但是不知道如何通过我找到的组创建一个新的列str数据。而且,我找到的几乎所有东西都是按单列分组的,而不是通过所有列的行。

sd2nnvve

sd2nnvve1#

这些代码可能有效

df = pd.DataFrame(np.random.randint(0,2, size=(12,8)))
df.columns=["col1","col2","col3","col4","col5","col6","col7","col8"]

def func(df:pd.DataFrame) -> pd.DataFrame:
    result_list = []
    copy = df.copy()
    cumsum = copy.cumsum(axis=1)

    for r,s in cumsum.iterrows():    
        count = 0
        last = -1
        interrupted = 0
        consecutive = 0
        consecutives = []    
        ranges = []   

        for x in s.values:
            count += 1
            if x != 0:
                if x!=last:
                    consecutive += 1
                    last = x            
                    if consecutive == 2:
                        ranges.append(count-1)
                elif x==last:
                    if consecutive > 1:
                        interrupted += 1
                        ranges.append(count-1) 
                        consecutives.append(str(consecutive))
                    consecutive = 0
        else:
            if consecutive > 1:
                consecutives.append(str(consecutive))
                ranges.append(count)                

        result = f'{interrupted}i/{len(consecutives)}c/{"-".join(consecutives)}/{"_".join([ f"c{ranges[i]}-c{ranges[i+1]}" for i in range(0,len(ranges),2) ])}/{last}'
        result_list.append(result.split("/"))

    copy["results"] = pd.Series(["/".join(i) for i in result_list])
    copy[["interrupts_count","consecutives_count","consecutives lengths","consecutives columns ranges","total"]] = pd.DataFrame(np.array(result_list))
    return copy

result_df = func(df)
ma8fv8wu

ma8fv8wu2#

可能会为每个列使用简单的类,这些列将接收来自原始DataFrame(即垂直切片)的系列和新值。使用原始DataFrame切片垂直数组计算所有起始值作为字段(连续真值的起始值、连续真值的长度、最后一个值..)。最后使用起始值和新的下一个值更新字段并准备字符串输出。

相关问题