根据索引、列名和原始值映射 Pandas 数据框?
Map Pandas dataframe based on index, column name and original value?
我想将数据帧的值映射到不同数据帧的值(也可能是字典)。
我要映射到的元素取决于三件事:
- 原值,
- 索引名称和
- 列名称。
例如我有以下数据框
df = pd.DataFrame(
data={"Feature_1": [-1, 1, 1, 3], "Feature_2": [0, 2, 2, 4]},
index=["00-1", "00-1", "00-2", "00-2"],
)
看起来像这样:
Feature_1 Feature_2
00-1 -1 0
00-1 1 2
00-2 1 2
00-2 3 4
还有另一个名为 mapping 的数据框,其中包含映射规则:
dict_01 = {"00-1": {"Feature_1": [0, "A", "B"], "Feature_2": [1, "C", "D"]},
"00-2": {"Feature_1": [2, "E", "F"], "Feature_2": [3, "G", "H"]}}
mapping = pd.DataFrame.from_dict(dict_01).transpose()
因此,映射如下所示:
Feature_1 Feature_2
00-1 [0, A, B] [1, C, D]
00-2 [2, E, F] [3, G, H]
我想根据某个阈值将每个元素映射到两个值之一。所有索引特征组合的阈值都不同。
在映射数据框中,每个列表的第一个元素代表阈值。
如果原始值小于此阈值,则应将其映射到列表的第二个元素。
如果大于等于,则映射到第三个元素。
我可以通过遍历行和列(见下文)来获得所需的结果。
df_mapped = df.copy()
for col in df_mapped.columns:
for row in range(len(df_mapped)):
idx = df_mapped.index[row]
if df_mapped[col].iloc[row] < mapping[col].loc[idx][0]:
df_mapped[col].iloc[row] = mapping[col].loc[idx][1]
else:
df_mapped[col].iloc[row] = mapping[col].loc[idx][2]
结果(df_mapped):
Feature_1 Feature_2
00-1 A C
00-1 B D
00-2 E G
00-2 F H
但实际数据集在两个维度(行和列)上都很大,我正在寻找一种有效的方法来计算它。
当使用 apply() 或 map() 之类的东西时,我似乎永远无法访问所需的所有三样东西(值、索引和列名)...
有没有一种有效的方法来达到预期的结果?
非常感谢!
从列表中用 MultiIndex
创建 DataFrame
,然后用 DataFrame.lt
, for select by each level use DataFrame.xs
, change index by DataFrame.reindex_like
and set values by mask by DataFrame.where
:
进行比较
comp = [pd.DataFrame(mapping[x].values.tolist(), index=mapping.index) for x in mapping.columns]
mapping1 = pd.concat(comp, axis=1, keys=mapping.columns)
print (mapping1)
Feature_1 Feature_2
0 1 2 0 1 2
00-1 0 A B 1 C D
00-2 2 E F 3 G H
mask = df.lt(mapping1.xs(0, level=1, axis=1))
df1 = (mapping1.xs(1, level=1, axis=1)
.reindex_like(df)
.where(mask, mapping1.xs(2, level=1, axis=1)))
print (df1)
Feature_1 Feature_2
00-1 A C
00-1 B D
00-2 E G
00-2 F H
我想将数据帧的值映射到不同数据帧的值(也可能是字典)。 我要映射到的元素取决于三件事:
- 原值,
- 索引名称和
- 列名称。
例如我有以下数据框
df = pd.DataFrame(
data={"Feature_1": [-1, 1, 1, 3], "Feature_2": [0, 2, 2, 4]},
index=["00-1", "00-1", "00-2", "00-2"],
)
看起来像这样:
Feature_1 Feature_2
00-1 -1 0
00-1 1 2
00-2 1 2
00-2 3 4
还有另一个名为 mapping 的数据框,其中包含映射规则:
dict_01 = {"00-1": {"Feature_1": [0, "A", "B"], "Feature_2": [1, "C", "D"]},
"00-2": {"Feature_1": [2, "E", "F"], "Feature_2": [3, "G", "H"]}}
mapping = pd.DataFrame.from_dict(dict_01).transpose()
因此,映射如下所示:
Feature_1 Feature_2
00-1 [0, A, B] [1, C, D]
00-2 [2, E, F] [3, G, H]
我想根据某个阈值将每个元素映射到两个值之一。所有索引特征组合的阈值都不同。 在映射数据框中,每个列表的第一个元素代表阈值。 如果原始值小于此阈值,则应将其映射到列表的第二个元素。 如果大于等于,则映射到第三个元素。
我可以通过遍历行和列(见下文)来获得所需的结果。
df_mapped = df.copy()
for col in df_mapped.columns:
for row in range(len(df_mapped)):
idx = df_mapped.index[row]
if df_mapped[col].iloc[row] < mapping[col].loc[idx][0]:
df_mapped[col].iloc[row] = mapping[col].loc[idx][1]
else:
df_mapped[col].iloc[row] = mapping[col].loc[idx][2]
结果(df_mapped):
Feature_1 Feature_2
00-1 A C
00-1 B D
00-2 E G
00-2 F H
但实际数据集在两个维度(行和列)上都很大,我正在寻找一种有效的方法来计算它。 当使用 apply() 或 map() 之类的东西时,我似乎永远无法访问所需的所有三样东西(值、索引和列名)... 有没有一种有效的方法来达到预期的结果? 非常感谢!
从列表中用 MultiIndex
创建 DataFrame
,然后用 DataFrame.lt
, for select by each level use DataFrame.xs
, change index by DataFrame.reindex_like
and set values by mask by DataFrame.where
:
comp = [pd.DataFrame(mapping[x].values.tolist(), index=mapping.index) for x in mapping.columns]
mapping1 = pd.concat(comp, axis=1, keys=mapping.columns)
print (mapping1)
Feature_1 Feature_2
0 1 2 0 1 2
00-1 0 A B 1 C D
00-2 2 E F 3 G H
mask = df.lt(mapping1.xs(0, level=1, axis=1))
df1 = (mapping1.xs(1, level=1, axis=1)
.reindex_like(df)
.where(mask, mapping1.xs(2, level=1, axis=1)))
print (df1)
Feature_1 Feature_2
00-1 A C
00-1 B D
00-2 E G
00-2 F H