Python:从数据框字符串列中提取维度数据,并为每个列创建具有值的列

Ann*_*ina 6 string extract dataframe python-3.x pandas

我有一个包含2列的源文件:ID和all_dimensions。所有维度都是具有不同“键值”对的字符串,每个ID都不相同。我想制作键列标题并解析相应的值(如果在正确的单元格中存在)。

例:

ID  all_dimensions
12  Height:2 cm,Volume: 4cl,Weight:100g
34  Length: 10cm, Height: 5 cm
56  Depth: 80cm
78  Weight: 2 kg, Length: 7 cm
90  Diameter: 4 cm, Volume: 50 cl
Run Code Online (Sandbox Code Playgroud)

所需结果:

ID  Height  Volume  Weight  Length  Depth  Diameter 
12  2 cm     4cl     100g      -      -        -
34  5 cm      -        -     10cm     -        -
56    -       -        -      -      80cm      -
78    -       -      2 kg    7 cm     -        -
90    -     50 cl     -       -      -        4 cm
Run Code Online (Sandbox Code Playgroud)

我确实有100多个维度,所以理想情况下,我想编写一个for循环或类似的方法以不指定每个列标题(请参见下面的代码示例),我正在使用Python 3.7.3和pandas 0.24.2。

我已经尝试了什么:

1)我试图将数据拆分为单独的列,但不确定如何继续将每个值分配到正确的标题中:

df.set_index('ID',inplace=True)
newdf = df["all_dimensions"].str.split(",|:",expand = True)
Run Code Online (Sandbox Code Playgroud)

2)使用初始df,我使用“ str.extract”创建新列(但随后我需要指定每个标头):

df['Volume']=df.all_dimensions.str.extract(r'Volume:([\w\s.]*)').fillna('')
Run Code Online (Sandbox Code Playgroud)

3)为了解决2)每个标题的问题,我创建了所有维属性的列表,并考虑将其与for循环一起使用以提取值:

columns_list=df.all_dimensions.str.extract(r'^([\D]*):',expand=True).drop_duplicates()
columns_list=columns_list[0].str.strip().values.tolist()
for dimension in columns_list:
    df.dimension=df.all_dimensions.str.extract(r'dimension([\w\s.]*)').fillna('')
Run Code Online (Sandbox Code Playgroud)

在这里,JupyterNB给了我一个UserWarning:“ Pandas不允许通过新的属性名称创建列”,并且df与以前一样。

Qua*_*ang 4

选项 1:我更喜欢分多次:

new_series = (df.set_index('ID')
                .all_dimensions
                .str.split(',', expand=True)
                .stack()
                .reset_index(level=-1, drop=True)
             )

# split second time for individual measurement
new_df = (new_series.str
                    .split(':', expand=True)
                    .reset_index()
                    )

# stripping off leading/trailing spaces
new_df[0] = new_df[0].str.strip()
new_df[1] = new_df[1].str.strip()

# unstack to get the desire table:
new_df.set_index(['ID', 0])[1].unstack()
Run Code Online (Sandbox Code Playgroud)

选项 2split(',|:') :按照您尝试过的方式使用:

# splitting
new_series = (df.set_index('ID')
                .all_dimensions
                .str.split(',|:', expand=True)
                .stack()
                .reset_index(level=-1, drop=True)
             )

# concat along axis=1 to get dataframe with two columns 
# new_df.columns = ('ID', 0, 1) where 0 is measurement name
new_df = (pd.concat((new_series[::2].str.strip(), 
                     new_series[1::2]), axis=1)
            .reset_index())

new_df.set_index(['ID', 0])[1].unstack()
Run Code Online (Sandbox Code Playgroud)

输出

    Depth   Diameter    Height  Length  Volume  Weight
ID                      
12  NaN     NaN     2 cm    NaN     4cl     100g
34  NaN     NaN     5 cm    10cm    NaN     NaN
56  80cm    NaN     NaN     NaN     NaN     NaN
78  NaN     NaN     NaN     7 cm    NaN     2 kg
90  NaN     4 cm    NaN     NaN     50 cl   NaN
Run Code Online (Sandbox Code Playgroud)