使用.loc,相同大小和不同索引的Series之间的值分配

时间:2019-03-08 21:57:43

标签: python pandas

我有一个问题,我有两个大小相等但索引不同的系列。我想将一个序列设置为与另一个序列相等。这可以通过重置索引来完成,但是在这种情况下,我使用.loc将DataFrame切片为Series。

设置

假设我有一个数据框:

df = pd.DataFrame({'name': ['a', 'b', 'a', 'b'], \
               'num':  [1, 1, 2, 2], \
               'val':  None})

  name  num   val
0    a    1  None
1    b    1  None
2    a    2  None
3    b    2  None

和两个带有值的系列:

vals_a = pd.Series([21,32])
vals_b = pd.Series([43,54])

所需结果

  name  num   val  vals
0    a    1  None  21.0
1    b    1  None  43.0
2    a    2  None  32.0
3    b    2  None  54.0

我的代码

df.loc[df.name == 'a', 'vals'] = vals_a
df.loc[df.name == 'b', 'vals'] = vals_b

  name  num   val  vals
0    a    1  None  21.0
1    b    1  None  54.0
2    a    2  None   NaN
3    b    2  None   NaN

这是我的问题的简化版本。实际上,vals_avals_b是具有可变索引的单独DataFrame的切片。我该如何切片,以便我的原始DataFrame将值存储在较小的Series中?

2 个答案:

答案 0 :(得分:4)

pandasindex敏感的,这意味着当您assign时,除了您在loc中提到的条件之外,它还会检查index匹配

df.loc[df.name == 'a', 'vals'] = vals_a.values
df.loc[df.name == 'b', 'vals'] = vals_b.values
df
Out[964]: 
  name  num   val  vals
0    a    1  None  21.0
1    b    1  None  43.0
2    a    2  None  32.0
3    b    2  None  54.0

答案 1 :(得分:1)

我能想到的最简单的方法是将map与迭代器的字典一起使用:

iter_a, iter_b = (iter(v) for v in (vals_a, vals_b))

mapping = {'a': iter_a, 'b': iter_b}
df['name'].map(lambda x: next(mapping[x]))

0    21
1    43
2    32
3    54
Name: name, dtype: int64