Python 如何使用字典值更新数据帧?
我有一个字典,它将每个唯一键映射到每个唯一值。我还有一个dataframe,它有一列包含所有这些键(可能多次)。与键列相邻的列具有需要由与另一列中的键关联的值替换的值 我尝试过使用iloc、where和update,但似乎无法使其正常工作Python 如何使用字典值更新数据帧?,python,pandas,dataframe,dictionary,Python,Pandas,Dataframe,Dictionary,我有一个字典,它将每个唯一键映射到每个唯一值。我还有一个dataframe,它有一列包含所有这些键(可能多次)。与键列相邻的列具有需要由与另一列中的键关联的值替换的值 我尝试过使用iloc、where和update,但似乎无法使其正常工作 df = pd.DataFrame({'1': ['A', 'B', 'C', 'D'], '2': ["alpha", 2.34, 0, 4.1234], '3': ["bravo", 2
df = pd.DataFrame({'1': ['A', 'B', 'C', 'D'],
'2': ["alpha", 2.34, 0, 4.1234],
'3': ["bravo", 20.123, 3.123123, 0],
'4': ["charlie", 20.123, 3.123123, 0],
'5': ["delta", 20.123, 3.123123, 0]},
index=['1', '2', '3', '4'])
还有字典
d = {'A': 2, 'B': 3, 'C': 5, 'D': 10}
这是合并的预期输出。您可以尝试以下操作:
df = pd.DataFrame(
{
"1": ["A", "B", "C", "D"],
"2": ["alpha", 2.34, 0, 4.1234],
"3": ["bravo", 20.123, 3.123123, 0],
"4": ["charlie", 20.123, 3.123123, 0],
"5": ["delta", 20.123, 3.123123, 0],
},
index=["1", "2", "3", "4"],
)
df["2"] = df["2"].astype("str")
将索引重置为列1
df = df.set_index("1")
使用系列
而不是字典;他们多少有些相似。注:我还将其命名为“2”
,因为我们要替换列2
d = pd.Series({"A": 2, "B": 3, "C": 5, "D": 10}, name="2")
您现在可以使用下面所示的两种方式之一进行连接。第一个保留列名后缀为\u old
的旧列,第二个简单地删除它
df = df.join(d, lsuffix="_old")
df = df[["3", "4", "5"]].join(d)
如果要恢复数值索引,可以再次重置索引:
df = df.reset_index(drop=False)
以下是第一种连接方式的输出:
1 2_old 3 4 5 2
0 A alpha bravo charlie delta 2
1 B 2.34 20.123 20.123 20.123 3
2 C 0 3.12312 3.12312 3.12312 5
3 D 4.1234 0 0 0 10
请注意,即使您的示例数据在1
中没有重复的值,上述内容仍然有效
在预期结果数据框中,显示新列具有字符串而不是整数。如果这是您的期望,那么在连接之前创建Series
对象时需要提供字符串
d = pd.Series({"A": "2", "B": "3", "C": "5", "D": "10"}, name="2")
或者你可以在事后改变它,就像这样:
df = pd.DataFrame(
{
"1": ["A", "B", "C", "D"],
"2": ["alpha", 2.34, 0, 4.1234],
"3": ["bravo", 20.123, 3.123123, 0],
"4": ["charlie", 20.123, 3.123123, 0],
"5": ["delta", 20.123, 3.123123, 0],
},
index=["1", "2", "3", "4"],
)
df["2"] = df["2"].astype("str")
编辑:由于OP正在寻找一种更简洁的方法来实现这一点,一种变体可能是:
d = pd.Series({"A": "2", "B": "3", "C": "5", "D": "10"}, name="2")
df = df.join(d, on="1", lsuffix="_old")
编辑2:根据OP的建议,另一个选项是使用系列。map
:
d = {"A": "2", "B": "3", "C": "5", "D": "10"}
df["2"] = df["1"].map(d)
编辑3:我做了一个快速性能测试;Series.map
方法的速度明显更快
In [34]: %timeit df.join(d, on="1", lsuffix="_old")
1.3 ms ± 58 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [35]: %timeit df["1"].map(d)
214 µs ± 3.56 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
设置索引和联接,可稍微提高join
方法的性能:
In [40]: foo = df.set_index("1")
In [41]: %timeit foo.join(d, lsuffix="_old")
818 µs ± 25.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
在您的输出中,看起来整个第一行都被替换了,这与提供的解释不相关。您的代码示例和描述不一致。根据您的描述,我希望有一个新的专栏,内容如下:
[2,3,5,10]
@suvayu抱歉复制了错误的数据帧。更新。如何将“2”:[“alpha”,2.34,0,4.1234]转换为“2”:[“2”,“3”,“5”,“10”]。我是否遗漏了什么或解释不一致。@vrana95,我只是要求使用字典来更新相应列的值。如果在本例中,数据类型和占位符值产生了巨大的差异,我可以更改它们,但基本前提保持不变。因此,理想情况下,您不必处理字典,两个对象都是数据帧?这应该归结为某种简单的合并/联接,此解决方案似乎太复杂了。它是联接!我添加了一个步骤来设置索引,以使连接更简单,并将dict
转换为Series
,从而可以进行连接。第三步是连接本身,我不知道您希望它简单多少。您可以删除set_index
步骤,并添加on=“2”
作为要联接的参数。这将它简化为两个步骤。@rye_-bread请检查编辑,我还修复了我在上面的注释中的打字错误df[“2”]=df[“1”]。映射(d)
似乎有效,而且简单得多?