给出一个示例pandas DataFrame:
Index | sometext | a | ff |
0 'asdff' 'b' 'g'
1 'asdff' 'c' 'hh'
2 'aaf' 'd' 'i'
使用该列中的数据替换[sometext]字段中所有列名称实例的最快方法是什么?要替换的值是特定于行的?
即。上述输入的期望结果将是:
Index | sometext | a | ff |
0 'bsdg' 'b' 'g'
1 'csdhh' 'c' 'hh'
2 'ddf' 'd' 'i'
注意:替换值不可能包含列名。
我已尝试迭代行,但随着DataFrame的长度和替换列的数量增加,执行时间逐渐消失。
Series.str.replace方法也会查看单个值,因此需要在每一行上运行。
答案 0 :(得分:2)
这种方式似乎很快。请参阅下面的简短讨论。
import re
df['new'] = df['sometext']
for v in ['a','ff']:
df['new'] = df.apply( lambda x: re.sub( v, x[v], x['new']), axis=1 )
结果:
sometext a ff new
0 asdff b g bsdg
1 asdff c hh csdhh
2 aaf d i ddf
讨论:
我将样本扩展到15,000行,与现有答案相比,这是最快的方法大约10倍或更多(尽管我怀疑可能有更快的方法)。
您希望使用列来进行行特定替换这一事实使得这个答案变得复杂(否则您只会做一个更简单的@wen df.replace
版本)。事实上,这种简单快速的方法需要我的方法和文件中的更多代码,尽管我认为它们或多或少地以相同的方式工作。
答案 1 :(得分:2)
我们可以这样做..
df.apply(lambda x : pd.Series(x['sometext']).replace({'a':x['a'],'ff':x['ff']},regex=True),1)
Out[773]:
0
0 bsdg
1 csdhh
2 ddf
答案 2 :(得分:0)
我有以下内容:
d = {'sometext': ['asdff', 'asdff', 'aaf'], 'a': ['b', 'c', 'd'], 'ff':['g', 'hh', 'i']}
df = pd.DataFrame(data=d)
start = timeit.timeit()
def replace_single_string(row_label, original_column, final_column):
result_1 = df.get_value(row_label, original_column)
result_2 = df.get_value(row_label, final_column)
if 'a' in result_1:
df.at[row_label, original_column] = result_1.replace('a', result_2)
else:
pass
return df
for i in df.index.values:
df = replace_single_string(i, 'sometext', 'a')
print df
end = timeit.timeit()
print end - start
在终端中以0.000404119491577秒运行。
答案 3 :(得分:0)
我找到的最快的方法是将apply函数与使用基本str.replace()方法的replacer函数串联使用。它内部非常快,即使有一个for循环,它也允许动态数量的列:
def value_replacement(df_to_replace, replace_col):
""" replace the <replace_col> column of a dataframe with the values in all other columns """
cols = [col for col in df_to_replace.columns if col != replace_col]
def replacer(rep_df):
""" function to by used in the apply function """
for col in cols:
rep_df[replace_col] = \
str(rep_df[replace_col]).replace(col.lower(), str(rep_df[col]))
return rep_df[replace_col]
df_to_replace[replace_col] = df_to_replace.apply(replacer, axis=1)
return df_to_replace