【问题标题】:Split dataframe by certain condition but keep the original dataframe按特定条件拆分数据帧,但保留原始数据帧
【发布时间】:2019-07-08 07:29:59
【问题描述】:

我有一个这样的数据框“bb”:

Response                                Unique Count
I love it so much!                      246_0    1
This is not bad, but can be better.     246_1    2
Well done, let's do it.                 247_0    1

如果 count 大于 1,我想拆分字符串并使数据框“bb”变成这样:(我预期的结果)

Response                                Unique
I love it so much!                      246_0    
This is not bad                         246_1_0    
but can be better.                      246_1_1
Well done, let's do it.                 247_0

我的代码:

bb = DataFrame(bb[bb['Count'] > 1].Response.str.split(',').tolist(), index=bb[bb['Count'] > 1].Unique).stack()
bb = bb.reset_index()[[0, 'Unique']]
bb.columns = ['Response','Unique']
bb=bb.replace('', np.nan)
bb=bb.dropna()
print(bb)

但是结果是这样的:

           Response  Unique
0  This is not bad    246_1
1  but can be better. 246_1

在这种情况下如何保留原始数据框?

【问题讨论】:

    标签: python pandas dataframe split


    【解决方案1】:

    首先使用新助手 Series 仅拆分每个条件的值,然后将 GroupBy.cumcount 的计数器值添加到 Index.duplicated 的重复索引值中:

    s = df.loc[df.pop('Count') > 1, 'Response'].str.split(',', expand=True).stack()
    df1 = df.join(s.reset_index(drop=True, level=1).rename('Response1'))
    df1['Response'] = df1.pop('Response1').fillna(df1['Response'])
    
    mask = df1.index.duplicated(keep=False)
    df1.loc[mask, 'Unique'] += df1[mask].groupby(level=0).cumcount().astype(str).radd('_')
    df1 = df1.reset_index(drop=True)
    print (df1)
                  Response   Unique
    0   I love it so much!    246_0
    1      This is not bad  246_1_0
    2   but can be better.  246_1_1
    3           Well done!    247_0
    

    编辑:如果需要 _0 为所有其他值删除掩码:

    s = df.loc[df.pop('Count') > 1, 'Response'].str.split(',', expand=True).stack()
    df1 = df.join(s.reset_index(drop=True, level=1).rename('Response1'))
    df1['Response'] = df1.pop('Response1').fillna(df1['Response'])
    
    df1['Unique'] += df1.groupby(level=0).cumcount().astype(str).radd('_')
    df1 = df1.reset_index(drop=True)
    print (df1)
                  Response   Unique
    0   I love it so much!  246_0_0
    1      This is not bad  246_1_0
    2   but can be better.  246_1_1
    3           Well done!  247_0_0
    

    【讨论】:

    • 非常整洁,谢谢!几分钟前编辑时,您是否也在其他 Unique 中最后添加了“_0”?我认为这是个好主意:)
    【解决方案2】:

    我们可以逐步解决这个问题:

    1. 按计数拆分数据帧
    2. 使用this 函数将字符串分解为行
    3. 我们在索引上使用groupby 并使用cumcount 来获取正确的unique 列值。
    4. 最后我们concat 再次将数据帧放在一起。

    df1 = df[df['Count'].ge(2)] # all rows which have a count 2 or higher
    df2 = df[df['Count'].eq(1)] # all rows which have count 1
    
    df1 = explode_str(df1, 'Response', ',') # explode the string to rows on comma delimiter
    
    # Create the correct unique column
    df1['Unique'] = df1['Unique'] + '_' + df1.groupby(df1.index).cumcount().astype(str)
    
    df = pd.concat([df1, df2]).sort_index().drop('Count', axis=1).reset_index(drop=True)
    
                  Response   Unique
    0   I love it so much!    246_0
    1      This is not bad  246_1_0
    2   but can be better.  246_1_1
    3           Well done!    247_0
    

    链接答案中使用的函数:

    def explode_str(df, col, sep):
        s = df[col]
        i = np.arange(len(s)).repeat(s.str.count(sep) + 1)
        return df.iloc[i].assign(**{col: sep.join(s).split(sep)})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-18
      • 2019-08-17
      • 1970-01-01
      • 1970-01-01
      • 2022-12-17
      • 1970-01-01
      • 2013-11-16
      相关资源
      最近更新 更多