在python中使用pandas根据其他列中给定的值选择列

2024-04-19 23:18:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据框,如下所示:

a   b   c   d......

1   1
3   3   3   5
4   1   1   4   6
1   0

我想根据列“a”中给定的值选择列数。在这种情况下,对于第一行,它将只选择列b。 我如何实现以下目标:

df.iloc[:,column b:number of columns corresponding to value in column a]

我的预期产出是:

a   b   c   d   e
1   1   0   0   1     # 'e' contains value in column b because colmn a = 1 
3   3   3   5   335   #  'e' contains values of column b,c,d because colm a 
4   1   1   4   1      #  = 3
1   0           NAN

Tags: columnsof数据innumber目标dfvalue
3条回答

一种numpy切片方法

a = v[:, 0]
b = v[:, 1:]
n, m = b.shape
b = b.ravel()
b = np.where(b == 0, '', b.astype(str))
r = np.arange(n) * m
f = lambda t: b[t[0]:t[1]]

df.assign(g=list(map(''.join, map(f, zip(r, r + a)))))

   a  b  c  d  e     g
0  1  1  0  0  0     1
1  3  3  3  5  0   335
2  4  1  1  4  6  1146
3  1  0  0  0  0      

编辑:带切片的单线解决方案

df["f"] = df.astype(str).apply(lambda r: "".join(r[1:int(r["a"])+1]), axis=1)

# df["f"] = df["f"].astype(int)  if you need `f` to be integer

df    
    a   b   c   d   e   f
0   1   1   X   X   X   1
1   3   3   3   5   X   335
2   4   1   1   4   6   1146
3   1   0   X   X   X   0

使用的数据集:

df = pd.DataFrame({'a': {0: 1, 1: 3, 2: 4, 3: 1},
                   'b': {0: 1, 1: 3, 2: 1, 3: 0},
                   'c': {0: 'X', 1: '3', 2: '1', 3: 'X'},
                   'd': {0: 'X', 1: '5', 2: '4', 3: 'X'},
                   'e': {0: 'X', 1: 'X', 2: '6', 3: 'X'}})

如有改进建议,将不胜感激

为此定义一个小函数:

def select(df, r):
    return df.iloc[r, 1:1 + df.iat[r, 0]]  

函数使用iat查询该行的a列,并使用iloc从同一行中选择列

可以这样称呼它:

select(df, 0)

b    1.0
Name: 0, dtype: float64

以及

select(df, 1)

b    3.0
c    3.0
d    5.0
Name: 1, dtype: float64

基于您的编辑,考虑此-

df

   a  b  c  d  e
0  1  1  0  0  0
1  3  3  3  5  0
2  4  1  1  4  6
3  1  0  0  0  0

在此处使用where/mask(带numpy广播)+agg

df['e'] = df.iloc[:, 1:]\
            .astype(str)\
            .where(np.arange(df.shape[1] - 1) < df.a[:, None], '')\
            .agg(''.join, axis=1)

df

   a  b  c  d     e
0  1  1  0  0     1
1  3  3  3  5   335
2  4  1  1  4  1146
3  1  0  0  0     0

如果没有匹配项,则e中的条目将有一个空字符串。只需使用replace-

df['e'] = df['e'].replace('', np.nan)

相关问题 更多 >