Добавить список в виде столбца на фрейм данных - PullRequest
3 голосов
/ 31 марта 2020

Предположим, у меня есть следующие списки:

cond_1 = [1,2]
cond_2 = [3,5]

А также следующий фрейм данных df:

|----------|
| Column_1 |
|----------|
|     x    |
|----------|
|     y    |
|----------|
|     y    |
|----------|
|     x    |
|----------|

Что я хочу сделать, это добавить второй столбец Column_2. Следуя этим критериям:

1) если Column_1 содержит x, добавьте значение в Column_2 из cond_1;

2), если Column_1 содержит y, добавьте значение в Column_2 из cond_2

Нужный вывод должен быть таким:

|----------|----------|
| Column_1 | Column_2 |
|----------|----------|
|     x    |     1    |
|----------|----------|
|     y    |     3    |
|----------|----------|
|     y    |     5    |
|----------|----------|
|     x    |     2    |
|----------|----------|

Я пытался сделать это, используя pd.Series:

df_x = df.loc[df['Column_1'] == "x"] #first I create a dataframe only with the x values
df_x['Column_2'] = pd.Series(cond_1)

Тогда я бы повторил то же самое для значений y, получив df_y.

Однако это не удалось. Затем мне нужно снова добавить два кадра данных (df_x и df_y), и я потеряю информацию об исходном индексе, который я хочу сохранить с df.

Ответы [ 4 ]

7 голосов
/ 31 марта 2020

Вы можете создать вспомогательный класс и использовать его в .apply, например:

class ReplaceWithNext:
    def __init__(self, **kwargs):
        self.lookup = {k: iter(v) for k, v in kwargs.items()}
    def __call__(self, value):
        return next(self.lookup[value])

Затем используйте его как:

df['Column_2' ] = df['Column_1'].apply(ReplaceWithNext(x=cond_1, y=cond_2))

, что даст вам:

  Column_1  Column_2
0        x         1
1        y         3
2        y         5
3        x         2
3 голосов
/ 31 марта 2020

Решение с l oop:

choice = ['x','y']
cond_1 = [1,2]
cond_2 = [3,5]
d = dict(zip(choice,np.vstack((cond_1,cond_2))))
#{'x': array([1, 2]), 'y': array([3, 5])}

for k,v in d.items():
    df.loc[df['Column_1'].eq(k),'Column2'] = v
print(df)

  Column_1  Column2
0        x      1.0
1        y      3.0
2        y      5.0
3        x      2.0
2 голосов
/ 31 марта 2020

Вы можете merge. pd.concat будет правильно перечислять индекс каждого элемента списков. Нам потребуется groupby + cumcount DataFrame, чтобы создать этот ключ.

s = pd.concat([pd.Series(l).rename('Column_2') for l in [cond_1, cond_2]], 
              keys=['x', 'y'], names=['Column_1', 'N'])

df['N'] = df.groupby('Column_1').cumcount()
df = df.merge(s, on=['Column_1', 'N'], how='left').drop(columns='N')

  Column_1  Column_2
0        x         1
1        y         3
2        y         5
3        x         2

Используя keys и names аргументы pd.concat, мы можем настроить Объединяющаяся серия, которая выглядит как ниже

print(s)
Column_1  N
x         0    1
          1    2
y         0    3
          1    5
Name: Column_2, dtype: int64
0 голосов
/ 31 марта 2020
df = pd.DataFrame({'Column_1':['x', 'y', 'y', 'x'], 'Column_2':['','','','']})

cond_1 = [1,2]
cond_2 = [3,5]

cond_1_idx = 0
cond_2_idx = 0

col_2_list = []
for idx, row in df.iterrows():
    if df.at[idx ,'Column_1'] == 'x':

        col_2_list.append(cond_1[cond_1_idx])
        cond_1_idx +=1

    if df.at[idx ,'Column_1'] == 'y':

        print( df.at[0 ,'Column_1'])
        col_2_list.append(cond_2[cond_2_idx])
        cond_2_idx +=1

df['Column_2'] = col_2_list

    Column_1    Column_2
0   x   1
1   y   3
2   y   5
3   x   2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...