作者:我们的北京宫 | 来源:互联网 | 2024-10-20 13:42
我目前有以下代码,使用字典对熊猫数据框进行一次编码,其中的键是要素名称,值是要素值列表。
def dummy_encode_dataframe(self,df,dummy_values_dict):
for (feature,dummy_values) in sorted(dummy_values_dict.items()):
for dummy_value in sorted(dummy_values):
dummy_name = u'%s_%s' % (feature,dummy_value)
df[dummy_name] = (df[feature] == dummy_value).astype(float)
del df[feature]
return df
dummy_values_dict
具有以下结构:
feature name (key) list of possible values (strings)
--------- ---------------------------------
F1 ['A','B','C','MISSING']
F2 ['D','E','F','MISSING']
F3 ['G','H','I']
带有示例输入/输出:
df (one row):
====
F1 F2 F3
--- ----- -----
'A' 'Q' 'H'
预期输出:
df_output:
====
F1_A F1_B F1_C F1_MISSING F2_D F2_E F2_F F2_MISSING F3_G F3_H F3_I
--- ---- ----- --------- ---- ---- ---- ---------- ---- ---- -----
1 0 0 0 0 0 0 0 0 1 0
问题在于for循环需要太长时间才能运行。有什么优化方法吗?
更新1:来自有关在scikit-learn中使用OneHotEncoder的评论...
您能否详细说明这段代码以获得所需的输出?
import pandas as pd
df = pd.DataFrame(columns=['F1','F2','F3'])
df.loc[0] = ['A','Q','H']
dummy_values_dict = { 'F1': ['A','MISSING'],'F2': ['D','F3': ['G','I'] }
# import OneHotEncoder
from sklearn.preprocessing import OneHotEncoder
categorical_cols = sorted(dummy_values_dict.keys())
# instantiate OneHotEncoder
# todo: encoding...
也许这个问题措辞不好。我设法使用下面的代码找到了一个更优化的实现(可能有更好的实现):
import pandas as pd
import numpy as np
def dummy_encode_dataframe_optimized(df,dummy_values_dict):
column_headers = np.concatenate(np.array(
[np.array([k + '_value_' + s
for s in sorted(dummy_values_dict[k])])
for k in sorted(dummy_values_dict.keys())]),axis=0)
feature_values = [str(feature) + '_value_' + str(df[feature][0])
for feature in dummy_values_dict.keys()]
one_hot_encode_vector = np.vectorize(lambda x: float(1) if x in feature_values else float(0))(column_headers)
untouched_df = df.drop(df.ix[:,dummy_values_dict.keys()].head(0).columns,axis=1)
hot_encoded_df = pd.concat(
[
untouched_df,pd.DataFrame(
[one_hot_encode_vector],index=untouched_df.index,columns=column_headers
)
],axis=1
)
return hot_encoded_df
df = pd.DataFrame(columns=['F1','F2','F3'])
df.loc[0] = ['A','Q','H']
dummy_values_dict = { 'F1': ['A','B','C','MISSING'],'F2': ['D','E','F','F3': ['G','H','I'] }
result = dummy_encode_dataframe_optimized(df,dummy_values_dict)
,
pd.get_dummies
应该适合您的情况,但是首先我们需要将不在字典中的所有值都设置为NaN
df = pd.DataFrame({'F1': ['A','F2': [
'Q','I',5]})
# F1 F2 F3
# 0 A Q G
# 1 B E H
# 2 C F I
# 3 MISSING MISSING 5
dummy_values_dict = {'F1': ['A','F2': [
'D','I']}
我们可以将所有其他值设置为np.nan
:
for col in df.columns:
df.loc[~df[col].isin(dummy_values_dict[col]),col] = np.nan
print(df)
# F1 F2 F3
# 0 A NaN G
# 1 B E H
# 2 C F I
# 3 MISSING MISSING NaN
然后我们可以使用pd.get_dummies
来完成这项工作:
print(pd.get_dummies(df))
# F1_A F1_B F1_C F1_MISSING F2_E F2_F F2_MISSING F3_G F3_H F3_I
# 0 1 0 0 0 0 0 0 1 0 0
# 1 0 1 0 0 1 0 0 0 1 0
# 2 0 0 1 0 0 1 0 0 0 1
# 3 0 0 0 1 0 0 1 0 0 0
请注意,如果我们没有一个值(例如“ F2”列中的“ D”),则不会出现“ F2_D”列,但是如果您确实需要该列,可以很容易地解决该问题