拆分并转换pandas中的字符串列

时间:2018-03-01 10:08:38

标签: python pandas

我正在处理一个软件的输出,该软件在一列中提供坐标作为x,y,z三元组。有没有办法将字符串分成三个独立的部分并一举转换成浮点数?例如,我知道我可以执行以下操作:

df['COORDFRONT'].str.split(' ').astype(float)

将三个字符串分开,但尝试例如

ValueError

返回ChoiceType

2 个答案:

答案 0 :(得分:4)

splitexpand=True一起用于DataFrame并通过双[]分配给子列中的新列:

df[['Front_x', 'Front_y', 'Front_z']] = df['COORDFRONT'].str.split(expand=True).astype(float)
print (df)
              COORDFRONT              COORDREAR    ID  Front_x  Front_y  \
0  787.547 238.639 0.000  803.545 230.467 0.000  3864  787.547  238.639   
1  787.141 238.847 0.000  803.139 230.675 0.000  3864  787.141  238.847   
2  786.729 239.057 0.000  802.727 230.885 0.000  3864  786.729  239.057   
3  786.310 239.271 0.000  802.309 231.099 0.000  3864  786.310  239.271   
4  785.886 239.488 0.000  801.884 231.316 0.000  3864  785.886  239.488   

   Front_z  
0      0.0  
1      0.0  
2      0.0  
3      0.0  
4      0.0  

如果列中没有NaN个值,请使用list comprehension

L = [x.split() for x in df['COORDFRONT'].values.tolist()]
df[['Front_x', 'Front_y', 'Front_z']] = pd.DataFrame(L).astype(float)

答案 1 :(得分:1)

这是一种方式:

df['Front_x'], df['Front_y'], df['Front_z'] = list(zip(*[list(map(float, i)) for i in \
                                                   df['COORDFRONT'].str.split(' ')]))

<强>结果

df.dtypes

# COORDFRONT     object
# COORDREAR      object
# ID              int64
# Front_x       float64
# Front_y       float64
# Front_z       float64
# dtype: object

<强>解释

  • map您的float结果中每行字符串值为split
  • 应用zip(*...)以输出分配给3个系列所需的3个数组。

<强>性能

为了在大型数据帧上获得更好的性能,请使用@jezrael's solution。一些基准测试结果如下。

df = pd.DataFrame({'ID': {0: 3864, 1: 3864, 2: 3864, 3: 3864, 4: 3864},
                   'COORDFRONT': {0: '787.547 238.639 0.000', 1: '787.141 238.847 0.000', 2: '786.729 239.057 0.000', 3: '786.310 239.271 0.000', 4: '785.886 239.488 0.000'},
                   'COORDREAR': {0: '803.545 230.467 0.000', 1: '803.139 230.675 0.000', 2: '802.727 230.885 0.000', 3: '802.309 231.099 0.000', 4: '801.884 231.316 0.000'}})

def jp(df):
    df['Front_x'], df['Front_y'], df['Front_z'] = list(zip(*[list(map(float, i)) for i in df['COORDFRONT'].str.split(' ')]))
    return df

def jez(df):
    df[['Front_x', 'Front_y', 'Front_z']] = df['COORDFRONT'].str.split(expand=True).astype(float)
    return df

# df = pd.concat([df]*100)
%timeit jp(df)   # 2.2ms
%timeit jez(df)  # 2.94ms

# df = pd.concat([df]*10000
%timeit jp(df)   # 154ms
%timeit jez(df)  # 127ms