我正在处理一个软件的输出,该软件在一列中提供坐标作为x,y,z三元组。有没有办法将字符串分成三个独立的部分并一举转换成浮点数?例如,我知道我可以执行以下操作:
df['COORDFRONT'].str.split(' ').astype(float)
将三个字符串分开,但尝试例如
ValueError
返回ChoiceType
。
答案 0 :(得分:4)
将split
与expand=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