替换数据框 MultiIndex 上的操作
Replace operation on a dataframe MultiIndex
我有两个数据框,我试图用另一个子字符串替换多索引级别 1 上的子字符串,但这失败了
例如我有一个数据框 df
Index0 Index1 0 1 2
A BX .2 .3 .9
CX .34 .55 .54
D EX .34 .44 .32
FX .43. .88. .06
我正在尝试 替换 Index1 子串 X 为 Y 这样我的结果
看起来如下
Index0 Index1 0 1 2
A BY .2 .3 .9
CY .34 .55 .54
D EY .34 .44 .32
FY .43. .88. .06
我正在使用以下功能
df.replace('X','Y')
但是我收到以下错误
AttributeError Traceback (most recent call last)
<ipython-input-56-fc7014a2d950> in <module>()
8
9
---> 10 df.replace('X','Y')
AttributeError: 'MultiIndex' object has no attribute 'replace'
@cᴏʟᴅsᴘᴇᴇᴅ 改进了我的回答所以我会在这里留下一个较慢的替代...
import numpy as np
df = pd.DataFrame(np.random.randn(4,3),
index=[list('aabb'), [n + 'X' for n in list('abcd')]])
这是使用 reset_index
的替代方法。如果您想在多列中进行替换,这将适用。诀窍是你不能在索引上使用 replace
所以你必须 "bring it into" DataFrame.
new = (df.reset_index()
.select_dtypes(include=['object'])
.apply(lambda col: col.str.replace('X', 'Y')))
df.index = pd.MultiIndex.from_tuples(new.values.tolist())
您所做的超出了您的需要。
df
0 1 2
Index0 Index1
A BX .2 .3 0.90
CX .34 .55 0.54
D EX .34 .44 0.32
FX .43. .88. 0.06
使用pd.MultiIndex.from_arrays
,一步完成。
df.index = pd.MultiIndex.from_arrays([df.index.get_level_values(0),
df.index.levels[1].str.replace('X', 'Y')])
df
0 1 2
Index0 Index1
A BY .2 .3 0.90
CY .34 .55 0.54
D EY .34 .44 0.32
FY .43. .88. 0.06
性能
%%timeit
new = (df.reset_index()
.select_dtypes(include=['object'])
.apply(lambda col: col.str.replace('X', 'Y')))
df.index = pd.MultiIndex.from_tuples(new.values.tolist())
10 loops, best of 3: 93.5 ms per loop
几乎 100ms
对于一个小数据帧。对比:
%%timeit
df.index = pd.MultiIndex.from_arrays([df.index.get_level_values(0),
df.index.levels[1].str.replace('X', 'Y')])
1000 loops, best of 3: 934 µs per loop
或者试试这个
df.index=pd.MultiIndex.from_tuples([(x[0], x[1].replace('X', 'Y')) for x in df.index])
df
Out[304]:
0 1 2
a aY -0.696181 -1.929523 -1.903956
bY 0.071061 -0.594185 -2.005251
b cY -0.097761 0.093667 1.780550
dY 0.127887 1.534395 0.352351
我有两个数据框,我试图用另一个子字符串替换多索引级别 1 上的子字符串,但这失败了
例如我有一个数据框 df
Index0 Index1 0 1 2
A BX .2 .3 .9
CX .34 .55 .54
D EX .34 .44 .32
FX .43. .88. .06
我正在尝试 替换 Index1 子串 X 为 Y 这样我的结果
看起来如下
Index0 Index1 0 1 2
A BY .2 .3 .9
CY .34 .55 .54
D EY .34 .44 .32
FY .43. .88. .06
我正在使用以下功能
df.replace('X','Y')
但是我收到以下错误
AttributeError Traceback (most recent call last)
<ipython-input-56-fc7014a2d950> in <module>()
8
9
---> 10 df.replace('X','Y')
AttributeError: 'MultiIndex' object has no attribute 'replace'
@cᴏʟᴅsᴘᴇᴇᴅ 改进了我的回答所以我会在这里留下一个较慢的替代...
import numpy as np
df = pd.DataFrame(np.random.randn(4,3),
index=[list('aabb'), [n + 'X' for n in list('abcd')]])
这是使用 reset_index
的替代方法。如果您想在多列中进行替换,这将适用。诀窍是你不能在索引上使用 replace
所以你必须 "bring it into" DataFrame.
new = (df.reset_index()
.select_dtypes(include=['object'])
.apply(lambda col: col.str.replace('X', 'Y')))
df.index = pd.MultiIndex.from_tuples(new.values.tolist())
您所做的超出了您的需要。
df
0 1 2
Index0 Index1
A BX .2 .3 0.90
CX .34 .55 0.54
D EX .34 .44 0.32
FX .43. .88. 0.06
使用pd.MultiIndex.from_arrays
,一步完成。
df.index = pd.MultiIndex.from_arrays([df.index.get_level_values(0),
df.index.levels[1].str.replace('X', 'Y')])
df
0 1 2
Index0 Index1
A BY .2 .3 0.90
CY .34 .55 0.54
D EY .34 .44 0.32
FY .43. .88. 0.06
性能
%%timeit
new = (df.reset_index()
.select_dtypes(include=['object'])
.apply(lambda col: col.str.replace('X', 'Y')))
df.index = pd.MultiIndex.from_tuples(new.values.tolist())
10 loops, best of 3: 93.5 ms per loop
几乎 100ms
对于一个小数据帧。对比:
%%timeit
df.index = pd.MultiIndex.from_arrays([df.index.get_level_values(0),
df.index.levels[1].str.replace('X', 'Y')])
1000 loops, best of 3: 934 µs per loop
或者试试这个
df.index=pd.MultiIndex.from_tuples([(x[0], x[1].replace('X', 'Y')) for x in df.index])
df
Out[304]:
0 1 2
a aY -0.696181 -1.929523 -1.903956
bY 0.071061 -0.594185 -2.005251
b cY -0.097761 0.093667 1.780550
dY 0.127887 1.534395 0.352351