我想保存数据框的一些属性并给定底层 numpy 数组的一部分,我想重建数据框,就好像我已经获取了数据框的一部分一样。如果对象列的值可以强制转换为浮点数,我想不出任何可行的方法。在真实的数据集中,我有数百万个观察值和数百列。
实际用例涉及 Pandas 与 scikit-learn 交互的自定义代码。我知道 scikit-learn 的最新版本与内置的 pandas 兼容,但我无法使用此版本,因为 RandomizedSearchCV 对象无法处理大参数网格(这将在未来版本中修复)。
data = [[2, 4, "Focus"],
[3, 4, "Fiesta",],
[1, 4, "300"],
[7, 3, "Pinto"]]
# This dataframe is exactly as intended
df = pd.DataFrame(data=data)
# Slice a subset of the underlying numpy array
raw_slice = df.values[1:,:]
# Try using the dtype option to force dtypes
df_dtype = pd.DataFrame(data=raw_slice, dtype=df.dtypes)
print "\n Dtype arg doesn't use passed dtypes \n", df_dtype.dtypes
# Try converting objects to numeric after reading into dataframe
df_convert = pd.DataFrame(data=raw_slice).convert_objects(convert_numeric=True)
print "\n Convert objects drops object values that are not numeric \n", df_convert
[Out]
Converted data does not use passed dtypes
0 object
1 object
2 object
dtype: object
Converted data drops object values that are not numeric
0 1 2
0 3 4 NaN
1 1 4 300
2 7 3 NaN
编辑:谢谢@unutbu 准确回答我的问题的答案。在 0.16.0 之前的 scikit-learn 版本中,gridsearch 对象从 pandas 数据帧中剥离了底层的 numpy 数组。这意味着单个对象列使整个数组成为对象,并且 pandas 方法不能包装在自定义转换器中。
使用@unutbu 的答案的解决方案是使管道的第一步成为自定义的“DataFrameTransformer”对象。
class DataFrameTransformer(BaseEstimator, TransformerMixin):
def __init__(self, X):
self.columns = list(X.columns)
self.dtypes = X.dtypes
def fit(self, X, y=None):
return self
def transform(self, X, y=None):
X = pd.DataFrame(X, columns=self.columns)
for col, dtype in zip(X, self.dtypes):
X[col] = X[col].astype(dtype)
return X
在管道中,只需在构造函数中包含您的原始 df :
pipeline = Pipeline([("df_converter", DataFrameTransformer(X)),
...,
("rf", RandomForestClassifier())])