Мой фрейм данных имеет 3 столбца:
File-Name
Time Stamp
File Size
При чтении добавляются строки, в которых имя файла слишком длинное. Для каждого такого случая мне нужно:
Здесь у меня есть строка 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.
Рассматривали ли вы вместо этого исправление метода чтения? Как выглядит файл, который вы читаете?
редактирование выглядит идеально. да, я думаю, я работал над более близким решением, но я не совсем уверен, как завершить этот процесс. этот метод будет использоваться для форматирования всех видов беспорядочных данных, и это основные прямые инструменты, которые я должен уметь использовать. у меня возникли проблемы с объединением имени файла. все, что я пытаюсь сделать, похоже, теряет данные или строки. спасибо за ясность в моем формате.
Ничего из предложений @ouroboros1 не помогает? Это выглядело довольно разумным ответом, хотя, возможно, вам было бы полезно получить больше пошаговых предложений.
Поскольку вы добавили «частичное решение» после того, как я опубликовал свой ответ , возможно, ваш df
сложнее, чем предполагает мой рабочий образец. Если да (и вообще), лучший способ найти решение — обновить ваш вопрос минимально воспроизводимым примером. Например, используйте df.to_dict()
, упростите образец и публикуйте сообщения между обратными кавычками (```), создавая df
, как я это сделал в своем ответе. Добавьте также ожидаемый результат на основе этого образца. Если у вас возникли конкретные проблемы с реализацией моего ответа, объясните их в комментарии ниже. Возможно, есть легкое решение.
превосходные решения. очень полезно. Спасибо. очень ясно, элегантно.
Вариант 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
Объяснение
df['File Size']
, проверьте условие Series.isna для df['File-Name']
и примените Series.shift с -1
, чтобы сдвинуть строки, которые необходимо добавить в df['File-Name']
, на одну строку назад.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
Объяснение
Series.where
на df2['File-Name']
: сохраните значение, если notna
, иначе получите df2['File Size']
и перезапишите исходный столбец «Имя файла» с помощью assign
.df.groupby
, передав наши группы (gr
), и примените groupby.agg . Для «Имени файла» нам нужно соединение . Для «Отметки времени» и «Размера файла» просто сначала введите.ваш код работал отлично Ouroboros1.
я придумал это как рабочее частичное решение и имею 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 записями. оба фрейма данных имеют одинаковый нумерованный индекс.
Добро пожаловать в ТАК! Я предложил внести изменения, чтобы уточнить ваше сообщение. Однако, похоже, вы не указали, «как это должно выглядеть» (предложение осталось неполным). Рассмотрите возможность добавления этой информации. Полагаю, вы хотите объединить две части строкового пути, так?