Вот фиктивный DataFrame:
d = {'col_1': [1, 2], 'col_n_1': [3, 4], 'col_2': [2, 1], 'col_n_2': [6, 3]}
df = pd.DataFrame(data=d)
col_1 col_2 col_n_1 col_n_2
0 1 2 3 6
1 2 1 4 3
2 1 1 4 5
Я ищу хороший способ извлечь значения из col_n_1
где col_1 == 1
и col_n_2
где col_2 == 1
в новом столбце, который будет выглядеть так:
new_col
3
3
4,5
Используйте, where
для получения значений по маске и затем join
столбцы:
L = ['col_1','col_2']
L1 = ['col_n_1','col_n_2']
df['new'] = (df[L1].astype(str).where(df[L].eq(1).values, axis=1)
.apply(lambda x: ','.join(x.dropna()), 1))
Решение, если только 2 столбца:
L = ['col_1','col_2']
L1 = ['col_n_1','col_n_2']
df1 = df[L1].astype(str).where(df[L].eq(1).values, axis=1)
df['new'] = (df1['col_n_1'] .fillna('') + ',' + df1['col_n_2'] .fillna('')).str.strip(',')
Или решение с дополнительными ,
а затем sum
, последний удалить задний ,
:
df['new'] = (df[L1].astype(str).where(df[L].eq(1).values)
.add(', ')
.fillna('')
.sum(axis=1)
.str.strip(', '))
print (df)
col_1 col_2 col_n_1 col_n_2 new
0 1 2 3 6 3
1 2 1 4 3 3
2 1 1 4 5 4,5
Заимствуйте список имен от Jez
df[L].eq(1).rename(columns=dict(zip(L,L1))).mul((df[L1].astype(str)+',')).sum(1).str[:-1]
Out[126]:
0 3
1 3
2 4,5
dtype: object
Это может быть выполнено с помощью метода apply()
и лямбда-функции. apply()
с параметром index
установленным в 1
, вызовет заданную функцию в каждой строке блока данных. Таким образом, единственная проблема заключается в написании этой функции - я считаю, что лучшим решением является создание списка, содержащего либо строку col_n_1
либо col_n_2
, либо, либо col_n_2
, а затем вхождение в список с запятыми. Как это:
df['new'] = df.apply(lambda row: ','.join([str(row.col_n_1)] if row.col_1 == 1 else [] + [str(row.col_n_2)] if row.col_2 == 1 else []), axis = 1)