根据idx系列设置数据帧值

时间:2018-05-25 21:24:07

标签: python pandas indexing

鉴于Dataframe df

A       B       C
0.10    0.83    0.07
0.40    0.30    0.30
0.70    0.17    0.13    
0.72    0.04    0.24    
0.15    0.07    0.78    

系列s

A    3
B    0
C    4
dtype: int64

有没有办法轻松设置
3的{​​{1}}元素,
A&列的0元素
B 4的{​​{1}}元素没有循环遍历系列?

徒劳无功:

C

(但这会设置整行)

所需的输出是:

df.loc[s] = 'spam'

2 个答案:

答案 0 :(得分:1)

有几种方法可以做到这一点。两者都需要将您的数据转换为object类型,以便将字符串分配给之前的float系列。

选项1:numpy

这要求您通过整数数组输入坐标,或者像这里一样输入元组列表。

import numpy as np

# convert to numpy object array
vals = df.values.astype(object)

# transform coordinates
coords = [(3, 0), (0, 1), (4, 2)]
idx = np.r_[coords].T

# apply indices
vals[idx[0], idx[1]] = 'spam'

# create new dataframe
res = pd.DataFrame(vals, index=df.index, columns=df.columns)

print(res)

      A     B     C
0   0.1  spam  0.07
1   0.4   0.3   0.3
2   0.7  0.17  0.13
3  spam  0.04  0.24
4  0.15  0.07  spam

选项2:pd.DataFrame.at

非向量化但更直接的解决方案是在for循环中使用pd.DataFrame.at

coords = [(3, 'A'), (0, 'B'), (4, 'C')]

df = df.astype(object)

for row, col in coords:
    df.at[row, col] = 'spam'

print(df)

      A     B     C
0   0.1  spam  0.07
1   0.4   0.3   0.3
2   0.7  0.17  0.13
3  spam  0.04  0.24
4  0.15  0.07  spam

答案 1 :(得分:0)

让我们成为上面定义的系列。

然后,我们首先将值设置为基础数组中的np.nan,然后分配'spam'

df.values[s.values, np.arange(s.size)] = np.nan # this modifies the dataframe in-place
df.fillna('spam', inplace=True)

输出:

      A     B     C
0   0.1  spam  0.07
1   0.4   0.3   0.3
2   0.7  0.17  0.13
3  spam  0.04  0.24
4  0.15  0.07  spam