Панды: как сохранить в другом новом кадре данных дублированную строку из столбца при изменении значения в другом столбце?

#python #pandas

Вопрос:

У меня есть фрейм данных Pandas, который выглядит так, df:

 text label
a    country
a    sport
b    cooking
b    cooking
c    travel
c    design
d    tech
 

Я хотел бы иметь два кадра данных. Один с дублированными строками из столбца «текст» при изменении значения в столбце «метка». А другой хранит все остальное.

Ожидаемые результаты, df1:

 text label
a    country
a    sport
c    travel
c    design
 

И df2:

 text label
b    cooking
b    cooking
d    tech
 

Ответ №1:

Используйте DataFrame.duplicated для проверки один или несколько столбцов для масок:

 m1 = df.duplicated('text', keep=False)
m2 = df.duplicated(['text','label'], keep=False)
#if all columns
#m2 = df.duplicated(keep=False)
mask = m2 | ~m1

df1 = df[~mask]
df2 = df[mask]

print (df1)
  text    label
0    a  country
1    a    sport
4    c   travel
5    c   design

print (df2)
  text    label
2    b  cooking
3    b  cooking
6    d     tech
 

Другой подход — проверить количество уникальных значений в группах-если они равны, нравится 1 или нет:

 mask = df.groupby('text')['label'].transform('nunique').eq(1)
df1 = df[~mask]
df2 = df[mask]
 

При изменении данных вывод будет другим:

 print (df)
  text    label
0    a  country
1    a    sport
2    a    sport
3    b  cooking
4    b  cooking
5    c   travel
6    c   design
7    d     tech
    

m1 = df.duplicated('text', keep=False)
m2 = df.duplicated(['text','label'], keep=False)
#if all columns
#m2 = df.duplicated(keep=False)
mask = m2 | ~m1

df1 = df[~mask]
df2 = df[mask]
print (df1)
  text    label
0    a  country
5    c   travel
6    c   design

print (df2)
  text    label
1    a    sport
2    a    sport
3    b  cooking
4    b  cooking
7    d     tech
 

 mask = df.groupby('text')['label'].transform('nunique').eq(1)
df1 = df[~mask]
df2 = df[mask]
print (df1)
  text    label
0    a  country
1    a    sport
2    a    sport
5    c   travel
6    c   design

print (df2)
  text    label
3    b  cooking
4    b  cooking
7    d     tech
 

Ответ №2:

 # get index of rows have duplicated `text`
duplicated = df.duplicated('text', keep=False)
duplicated_index = duplicated[duplicated == True].index

# select df1 and df2 according to this index
df1 = df.loc[duplicated_index].reset_index(drop=True)
df2 = df.loc[set(df.index) - set(duplicated_index)].reset_index(drop=True)

# we get
df1
  text    label
0    a  country
1    a    sport
2    c   travel
3    c  designe

df2
  text    label
0    b  cooking
1    d     tech