Создать новый столбец, только если значения отличаются - PullRequest
0 голосов
/ 24 сентября 2018

Мой фрейм данных выглядит так:

pd.DataFrame([["t1","d2","e3","r4"],
         ["t1","d2","e2","r4"],
         ["t1","d2","e1","r4"]],columns=["a","b","c","d"])

, и я хочу:

pd.DataFrame([["t1","d2","e3","r4","e1","e2"]],
columns=["a","b","c","d","c1","c2"])

т.е. у меня есть только 1 столбец, значения которого отличаются, и я хочу создать новый фрейм данных со столбцамидобавляется, когда наблюдаются новые значения.Есть ли простой способ сделать это?

Ответы [ 4 ]

0 голосов
/ 24 сентября 2018

Использование drop_duplicates

s=df.reset_index().melt('index').drop_duplicates(['variable','value'],keep='first')


pd.DataFrame([s.value.values.tolist()],columns=s['variable']+s['index'].astype(str))
Out[1151]: 
   a0  b0  c0  c1  c2  d0
0  t1  d2  e3  e2  e1  r4
0 голосов
/ 24 сентября 2018

Не так красиво, как ответ Скотта, но логика, которую вы ищете:

out = pd.DataFrame()
for col in df.columns:
    values =df[col].unique()
    if len(values)==1:
        out[col]=values
    else:
        for i,value in enumerate(values):
            out[col+str(i+1)]= value
0 голосов
/ 24 сентября 2018

Вы можете использовать словарь понимания.Для согласованности я включил целочисленную маркировку во все столбцы.

res = pd.DataFrame({f'{col}{idx}': val for col in df for idx, val in \
                    enumerate(df[col].unique(), 1)}, index=[0])

print(res)

   a1  b1  c1  c2  c3  d1
0  t1  d2  e3  e2  e1  r4

Альтернативой df[col].unique() является df[col].drop_duplicates(), хотя последний может повлечь за собой дополнительные издержки для итерации объекта pd.Series против np.ndarray.

0 голосов
/ 24 сентября 2018

Редактировать: Обобщение для любого неуникального столбца:

Ucols = df.columns[(df.nunique() == 1)].tolist()
df_out = df.set_index(Ucols).set_index(df.groupby(Ucols).cumcount(), append=True).unstack()
df_out.columns = [f'{i}{j}' if j != 0 else f'{i}' for i,j in df_out.columns]
print(df_out.reset_index())

Вывод:

    a   b   d   c  c1  c2
0  t1  d2  r4  e3  e2  e1

Исходный ответ

Использование:

df_out = df.set_index(['a','b','d',df.groupby(['a','b','d']).cumcount()]).unstack()

df_out.columns = [f'{i}{j}' if j != 0 else f'{i}' for i,j in df_out.columns]

df_out.reset_index()

Выход:

    a   b   d   c  c1  c2
0  t1  d2  r4  e3  e2  e1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...