如何用字典值更新数据框?

时间:2019-06-03 01:22:34

标签: python pandas dataframe dictionary

我有一个字典,其中包含每个唯一键到每个唯一值的映射。我还有一个数据框,该数据框的一列包含所有这些键(可能多次)。与键列相邻的一列具有需要替换为与另一列中的键相关联的值的值。

我尝试使用iloc,where和update,但似乎无法正常工作。

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': ["2", "3", "5", "10"],
                  '3': [7, 20.123, 3.123123, 0],
                   '4': [9, 20.123, 3.123123, 0],
                   '5': [11, 20.123, 3.123123, 0]},

                 index=['1', '2', '3', '4'])

这是合并的预期输出。

1 个答案:

答案 0 :(得分:1)

您可以尝试这样的事情:

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"],
)

将索引重置为列1

df = df.set_index("1")

使用Series代替字典;它们或多或少相似。请注意,由于我们要替换列"2",因此我也将其命名为2

d = pd.Series({"A": 2, "B": 3, "C": 5, "D": 10}, name="2")

您现在可以使用以下两种方式中的任何一种来加入。第一个保留列名后缀为_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["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所建议,另一种选择是使用Series.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)