У меня есть следующий пандас dataframe -

df = 
    1.0         2.0         3.0             4.0         5.0
(1083, 596)                             (1050, 164)   (1050, 164)   
(1081, 595)                             (1050, 164)   (1080, 162)
(1081, 594)                             (1049, 163)   (1070, 164)
(1082, 593) 
            (1050, 164)     
            (1050, 164)     
            (1049, 163)     
            (1049, 163)     

                        (1052, 463)
                        (1051, 468)
                        (1054, 465)
                        (1057, 463)

Мне нужен совершенно новый фрейм данных df2 с 3 столбцами: 1.0, 2.0 (объединяет 2.0 и 4.0) и 3.0 (объединяет 3.0 и 5.0).

Результат будет -

df2 = 
    1.0         2.0         3.0     
(1083, 596) (1050, 164)   (1050, 164)   
(1081, 595) (1050, 164)   (1080, 162)
(1081, 594) (1049, 163)   (1070, 164)
(1082, 593) 
            (1050, 164)     
            (1050, 164)     
            (1049, 163)     
            (1049, 163)     

                        (1052, 463)
                        (1051, 468)
                        (1054, 465)
                        (1057, 463)

Вы можете ожидать, что в объединенных столбцах не будет перекрывающихся значений; если один столбец имеет допустимое значение в строке, то другие будут иметь значение NaN.

Я старался -

df.fillna(0)
df2['2.0']=df['2.0']+df['4.0']

И это не работает, как задумано. Есть ли простой и эффективный способ сделать это?

0
Sourav 9 Июл 2019 в 20:53

3 ответа

Лучший ответ

Вы можете использовать DataFrame.where() и DataFrame.isnull(), чтобы смешать значения так, как вы пытаетесь:

df2 = pd.DataFrame(df["1.0"], columns=["1.0"])
df2["2.0"] = df["2.0"].where(~df2["2.0"].isnull(), df2["4.0"])
df2["3.0"] = df["3.0"].where(~df2["3.0"].isnull(), df2["5.0"])
1
Akaisteph7 9 Июл 2019 в 18:11

Предположим, что пробелами в df являются NaN с. Вам нужно только сместить столбцы '2.0, 3.0, 4.0, 5.0' влево на 2 позиции и сделать combine_first с df. Наконец, выберите первые 3 столбца, используя iloc

df2 = df.combine_first(df.drop('1.0',1).shift(-2, axis=1)).iloc[:,:3]

Out[297]:
           1.0         2.0         3.0
0   (1083, 596)  (1050, 164)  (1050, 164)
1   (1081, 595)  (1050, 164)  (1080, 162)
2   (1081, 594)  (1049, 163)  (1070, 164)
3   (1082, 593)         NaN         NaN
4          NaN  (1050, 164)         NaN
5          NaN  (1050, 164)         NaN
6          NaN  (1049, 163)         NaN
7          NaN  (1049, 163)         NaN
8          NaN         NaN  (1052, 463)
9          NaN         NaN  (1051, 468)
10         NaN         NaN  (1054, 465)
11         NaN         NaN  (1057, 463)
1
Andy L. 9 Июл 2019 в 19:24

Просто в основном копирование и вставка. Я думаю, что это работает.

# copy values over to your other columns
# note: [0:3,'2.0'] gets the first 4 rows (index 0 to 3) of column '2.0'
# then you set it equal to the first 4 rows of column '4.0'

df.loc[0:3,'2.0'] = df.loc[0:3,'4.0'] 
df.loc[0:3,'3.0'] = df.loc[0:3,'5.0'] 


# just get the three columns you need


df2 = df[['1.0','2.0','3.0']]


           1.0          2.0          3.0
0   (1083, 596)  (1050, 164)  (1050, 164)
1   (1081, 595)  (1050, 164)  (1080, 162)
2   (1081, 594)  (1049, 163)  (1070, 164)
3   (1082, 593)          NaN          NaN
4           NaN  (1050, 164)          NaN
5           NaN  (1050, 164)          NaN
6           NaN  (1049, 163)          NaN
7           NaN  (1049, 163)          NaN
8           NaN          NaN          NaN
9           NaN          NaN  (1052, 463)
10          NaN          NaN  (1051, 468)
11          NaN          NaN  (1054, 465)
12          NaN          NaN  (1057, 463)

Если ваши имена столбцов на самом деле плавающие, удалите кавычки из этих разделов: df.loc[0:3,'2.0'] например, изменить на df.loc[0:3,2.0] вроде:

df.loc[0:3,2.0] = df.loc[0:3,4.0] 
df.loc[0:3,3.0] = df.loc[0:3,5.0] 
1
SCool 9 Июл 2019 в 18:32