更有效的方法来清理字符串列并添加新列

use*_*486 8 python apply pandas

我有一个df包含列的数据框['metric_type', 'metric_value'].对于每一行,我想确保我有一个名称等于的列,该列'metric_type'的值等于'metric_value'.

我的一个问题是'metric_type'我想要摆脱虚假的空间.

考虑数据帧df:

df = pd.DataFrame([
        ['a ', 1],
        [' b', 2],
        [' c ', 3]
    ], columns=['metric_type', 'metric_value'])

print(df)

  metric_type  metric_value
0          a              1
1           b             2
2          c              3
Run Code Online (Sandbox Code Playgroud)

请注意,每个值'metric_type'都有不同位置的空格.

我创建了一个使用的功能,apply但需要花费很长时间.

def assign_metric_vals(row):
    row[row['metric_type'].replace(" ", "")] = row['metric_value']
    return row
Run Code Online (Sandbox Code Playgroud)

当我使用它时,我得到这个:

       a    b    c metric_type  metric_value
0 1.0000  nan  nan          a              1
1    nan 2.00  nan           b             2
2    nan  nan 3.00          c              3
Run Code Online (Sandbox Code Playgroud)

是否有更好的(阅读,"更快")方式来完成同样的任务?

piR*_*red 11

您可以更好地设置索引metric_type和取消堆栈.

df.set_index(df.metric_type.str.replace(' ', ''), append=True).metric_value.unstack()
Run Code Online (Sandbox Code Playgroud)

示范

df = pd.DataFrame([
        ['a ', 1],
        [' b', 2],
        [' c ', 3]
    ], columns=['metric_type', 'metric_value'])

print(df)

  metric_type  metric_value
0          a              1
1           b             2
2          c              3

print(df.apply(assign_metric_vals, 1))

       a    b    c metric_type  metric_value
0 1.0000  nan  nan          a              1
1    nan 2.00  nan           b             2
2    nan  nan 3.00          c              3
Run Code Online (Sandbox Code Playgroud)

或者我的方式

idx = df.metric_type.str.replace(' ', '')
d1 = df.set_index(idx, append=True).metric_value.unstack()
print(pd.concat([d1, df], axis=1))

       a    b    c metric_type  metric_value
0 1.0000  nan  nan          a              1
1    nan 2.00  nan           b             2
2    nan  nan 3.00          c              3
Run Code Online (Sandbox Code Playgroud)

定时

用一个更大的 df
df1 = pd.concat([df] * 30000, ignore_index=True)

%%timeit
idx = df1.metric_type.str.replace(' ', '')
d1 = df1.set_index(idx, append=True).metric_value.unstack()
pd.concat([d1, df1], axis=1)
Run Code Online (Sandbox Code Playgroud)

10个循环,最佳3:每循环77.3毫秒

%%timeit
df1.apply(assign_metric_vals, 1)
Run Code Online (Sandbox Code Playgroud)

1个循环,最佳3:每循环57.4秒