Как объединить/объединить две строки после того, как длинные столбцы были неправильно прочитаны в отдельные строки?

Мой фрейм данных имеет 3 столбца:

  • File-Name
  • Time Stamp
  • File Size

При чтении добавляются строки, в которых имя файла слишком длинное. Для каждого такого случая мне нужно:

  • объединить две строки
  • удалите значения None и NaN
  • наконец удалите лишнюю строку.

Здесь у меня есть строка 20 и строка 21. Строка 21 — это превышение пути и имени файла:

20  ./.c9/dependencies/extensionHost/956a43f1ecc7f34424174768925cd9cc5a3e006d2ad71e6bd939f2a    2024-04-17 12:56    135268
21  None    NaN e04e9ef74933c4cab24ec0f62a973d0b06e59e466286a73382db011071887b5eafad4b8b9/package

Вот как это должно выглядеть...

И снова для строки 74 была создана еще одна дополнительная строка:

70  ./.nvm/versions/node/v20.12.0/include/node/ope...   2024-03-26 16:18    53440
71  ./.cache/node-gyp/18.19.0/include/node/openssl...   2024-03-06 19:24    53440
72  ./.nvm/versions/node/v20.11.1/include/node/ope...   2024-02-13 23:50    53440
73  ./.c9/node/include/node/openssl/archs   2023-11-29 14:59    53440
74  ./.c9/dependencies/node18-linux-x64/7e2ea6e5ed...   2023-11-29 14:59    53440
75  None    NaN 85de0311e77fec00f3ce2303de1affbe390e7b22b96402...

Я пытаюсь использовать слияние или объединить все строки со значениями NaN.

Добро пожаловать в ТАК! Я предложил внести изменения, чтобы уточнить ваше сообщение. Однако, похоже, вы не указали, «как это должно выглядеть» (предложение осталось неполным). Рассмотрите возможность добавления этой информации. Полагаю, вы хотите объединить две части строкового пути, так?

OCa 30.04.2024 10:55

Рассматривали ли вы вместо этого исправление метода чтения? Как выглядит файл, который вы читаете?

OCa 30.04.2024 10:56

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

tooDeeStoned 30.04.2024 22:13

Ничего из предложений @ouroboros1 не помогает? Это выглядело довольно разумным ответом, хотя, возможно, вам было бы полезно получить больше пошаговых предложений.

OCa 30.04.2024 23:20

Поскольку вы добавили «частичное решение» после того, как я опубликовал свой ответ , возможно, ваш df сложнее, чем предполагает мой рабочий образец. Если да (и вообще), лучший способ найти решение — обновить ваш вопрос минимально воспроизводимым примером. Например, используйте df.to_dict(), упростите образец и публикуйте сообщения между обратными кавычками (```), создавая df, как я это сделал в своем ответе. Добавьте также ожидаемый результат на основе этого образца. Если у вас возникли конкретные проблемы с реализацией моего ответа, объясните их в комментарии ниже. Возможно, есть легкое решение.

ouroboros1 02.05.2024 11:28

превосходные решения. очень полезно. Спасибо. очень ясно, элегантно.

tooDeeStoned 02.05.2024 16:00
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
6
82
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вариант 1 (всегда только одна завершающая ошибочная строка)

Минимально воспроизводимый пример

import pandas as pd
import numpy as np

data = {'File-Name': {0: 'file', 1: None, 2: 'file2', 3: 'file', 4: None}, 
         'Time Stamp': {0: '2024-01-01 00:00:00', 1: np.nan, 2: '2024-01-01 00:00:00', 
                       3: '2024-01-01 00:00:00', 4: np.nan}, 
         'File Size': {0: 1, 1: '1_too_long', 2: 2, 3: 3, 4: '3_too_long'}
         }
df = pd.DataFrame(data)

df

  File-Name           Time Stamp   File Size
0      file  2024-01-01 00:00:00           1
1      None                  NaN  1_too_long
2     file2  2024-01-01 00:00:00           2
3      file  2024-01-01 00:00:00           3
4      None                  NaN  3_too_long

Код

out = (
    df.assign(**{'File-Name': (df['File-Name'] + (df['File Size']
                                                  .where(df['File-Name'].isna())
                                                  .shift(-1)
                                                  .fillna(''))
                               )
                 }
              )
    .dropna(subset='File-Name')
    .reset_index(drop=True)
)

Выход

        File-Name           Time Stamp File Size
0  file1_too_long  2024-01-01 00:00:00         1
1           file2  2024-01-01 00:00:00         2
2  file3_too_long  2024-01-01 00:00:00         3

Объяснение

  • Используйте Series.where для df['File Size'], проверьте условие Series.isna для df['File-Name'] и примените Series.shift с -1, чтобы сдвинуть строки, которые необходимо добавить в df['File-Name'], на одну строку назад.
  • Добавьте Series.fillna , чтобы преобразовать значения NaN в пустую строку (''), добавьте к df['File-Name'] и перезапишите исходный столбец с помощью df.assign.
  • Теперь избавьтесь от строк None с помощью df.dropna на subset='File-Name' и df.reset_index для нового непрерывного индекса.

Вариант 2 (возможность наличия более одной завершающей ошибочной строки)

Вариант 1 не будет работать должным образом, если имена файлов настолько длинные, что в конце имеется несколько строк. В этом случае мы можем использовать df.groupby:

Образец

data2 = {'File-Name': {0: 'file', 1: None, 2: 'file2', 3: 'file', 4: None, 5: None}, 
         'Time Stamp': {0: '2024-01-01 00:00:00', 1: np.nan, 2: '2024-01-01 00:00:00', 
                       3: '2024-01-01 00:00:00', 4: np.nan, 5: np.nan}, 
         'File Size': {0: 1, 1: '1_too_long', 2: 2, 3: 3, 4: '3_way', 5: '_too_long'}
         }
df2 = pd.DataFrame(data2)

df2

  File-Name           Time Stamp   File Size
0      file  2024-01-01 00:00:00           1
1      None                  NaN  1_too_long
2     file2  2024-01-01 00:00:00           2
3      file  2024-01-01 00:00:00           3
4      None                  NaN       3_way # multiple rows
5      None                  NaN   _too_long # multiple rows

Код

gr = df2['File-Name'].notna().cumsum()

out2 = (
    df2.assign(**{'File-Name': df2['File-Name'].where(df2['File-Name'].notna(), 
                                                df2['File Size'])
                  }
               )
    .groupby(gr, as_index=False)
    .agg({'File-Name': lambda x: ''.join(x), 
          'Time Stamp': 'first', 
          'File Size': 'first'})
)

Выход

            File-Name           Time Stamp File Size
0      file1_too_long  2024-01-01 00:00:00         1
1               file2  2024-01-01 00:00:00         2
2  file3_way_too_long  2024-01-01 00:00:00         3

Объяснение

ваш код работал отлично Ouroboros1.

tooDeeStoned 02.05.2024 15:51

я придумал это как рабочее частичное решение и имею 2 фрейма данных. один с усеченными именами файлов, а другой - просто заглушка имени файла: вот список строк 13-16 из df1 (15 - отсутствующий индекс)

13 ./.c9/зависимости/node18-linux-x64 2024-03-06 19:27 166940 14 ./.c9/зависимости/node18-linux-x64/7e2ea6e5edddeede43c966070975591a581c4ae0792a9b1a8af6 06.03.2024 19:27 166936 16 ./.nvm/versions/node/v20.12.0 29.03.2024 19:09 153080

и строки 14,18, 20 из df2

14 85de0311e77fec00f3ce2303de1affbe390e7b22b96402f66e9354a817ac84e6e0cd7eb74bd1 18 e04e9ef74933c4cab24ec0f62a973d0b06e59e466286a73382db011071887b5eafad4b8b9 20 e04e9ef74933c4cab24ec0f62a973d0b06e59e466286a73382db011071887b5eafad4b8b9/package

первый имеет примерно 800 строк, второй - около 250. У них есть соответствующий номер индекса для строк. мой код был довольно простым:

''' drop_null_df = df.dropna()

null_rows = df.loc[df["Имя-файла:"].isnull()]

null_rows = null_rows.rename(индекс = лямбда x: x - 1) '''

я удалил и переименовал столбцы, оставив одно имя столбца «Имя-файла:» в null_rows df.

я хочу объединить строку имени файла с заглушкой из записей null_rows 200 в столбец drop_null_df «Имя файла:» с 800 записями. оба фрейма данных имеют одинаковый нумерованный индекс.

Другие вопросы по теме