在Pandas Dataframe Cell中处理多个值

ulydmbyx  于 2023-04-28  发布在  其他
关注(0)|答案(2)|浏览(121)

列是数据的描述,行保留值。然而,在某些列中有多个值(网站上的表格形式)。这些表格的行合并在一个单元格中,并由主题标签分隔。由于它们只是表格的一部分,因此它们引用其他列,其中单元格中的值也由主题标签分隔。

Column Name: solution_id | type labour | labour_unit    | est_labour_quantity | est_labour_costs | est_labour_total_costs
             10          | WorkA#WorkB | Person#Person  | 2.0#2.0             | 300.0#300.0.     | 600.0#600.0     
             11          | WorkC#WorkD | Person#Person  | 3.0#2.0             | 300.0#300.0.     | 900.0#600.0

我的问题有两个:
1.什么是转换数据以更有效地处理它的好方法,例如,创建与一个单元格中的条目一样多的新列。

Column Name: solution_id | type labour_1 | labour_unit_1    | est_labour_quantity_1 | est_labour_costs_1 | est_labour_total_costs_1 | type labour_2 | labour_unit_2    | est_labour_quantity_2 | est_labour_costs_2 | est_labour_total_costs_2
             10          | WorkA         | Person.          | 2.0.                  | 300.0.             | 600.0.                   | WorkB         | Person           | 2.0                   | 300.0              | 600.0     
             11          | WorkC         | Person.          | 3.0.                  | 300.0.             | 900.0.                   | WorkD         | Person           | 2.0                   | 300.0              | 600.0

这使得它更可读,但它的列数增加了一倍,我有一些单元格最多有5个条目,所以它将是x5多列。我也不喜欢这个想法的是,新的列名没有真正意义,很难解释它们。
1.我如何在pandas中进行这种分离,以便我有WorkA,然后是相关的值,然后是Work B等。
如果有其他更好的方法来处理这个表格形式,也许把它都放在一个单元格里?请让我知道!

3duebb1j

3duebb1j1#

用途:

#unpivot by melt
df = df.melt('solution_id')
#create lists by split #
df['value'] = df['value'].str.split('#')
#repeat rows by value column
df = df.explode('value')
#counter for new columns names
df['g'] = df.groupby(['solution_id','variable']).cumcount().add(1)

#pivoting and sorting MultiIndex
df = (df.pivot('solution_id',['variable', 'g'], 'value')
         .sort_index(level=1, axis=1, sort_remaining=False))

#flatten MultiIndex
df.columns = df.columns.map(lambda x: f'{x[0]}_{x[1]}')
print (df)
            type_labour_1 labour_unit_1 est_labour_quantity_1  \
solution_id                                                     
10                  WorkA        Person                   2.0   
11                  WorkC        Person                   3.0   

            est_labour_costs_1 est_labour_total_costs_1 type_labour_2  \
solution_id                                                             
10                       300.0                    600.0         WorkB   
11                       300.0                    900.0         WorkD   

            labour_unit_2 est_labour_quantity_2 est_labour_costs_2  \
solution_id                                                          
10                 Person                   2.0             300.0.   
11                 Person                   2.0             300.0.   

            est_labour_total_costs_2  
solution_id                           
10                             600.0  
11                             600.0
66bbxpm5

66bbxpm52#

您可以拆分字符串,分解和重塑:

df2 = (df
 .set_index('solution_id')
 .apply(lambda c: c.str.split('#'))
 .explode(list(df.columns[1:]))
 .assign(idx=lambda d: d.groupby(level=0).cumcount().add(1))
 .set_index('idx', append=True)
 .unstack('idx')
 .sort_index(axis=1, level='idx', sort_remaining=False)
)

df2.columns = [f'{a}_{b}' for a,b in df2.columns]

输出:

type labour_1 labour_unit_1 est_labour_quantity_1 est_labour_costs_1 est_labour_total_costs_1 type labour_2 labour_unit_2 est_labour_quantity_2 est_labour_costs_2 est_labour_total_costs_2
solution_id                                                                                                                                                                                            
10                  WorkA        Person                   2.0              300.0                    600.0         WorkB        Person                   2.0             300.0.                    600.0
11                  WorkC        Person                   3.0              300.0                    900.0         WorkD        Person                   2.0             300.0.                    600.0

或者,使用相同的初始分割,然后进行切片和级联的较短代码:

df2=(df
 .set_index('solution_id')
 .apply(lambda c: c.str.split('#'))
)
pd.concat([df2.apply(lambda c: c.str[i]).add_suffix(f'_{i+1}')
           for i in range(len(df2.iat[0,0]))], axis=1)

相关问题