У меня есть файл csv -
CSV А-
Date/Time Num
2023/04/10 14:13:18 6122
2023/04/10 14:14:24 6005
2023/04/10 14:14:59 6004
Там будет максимум 3 строки или меньше, также всегда будет Num=6122. Две другие строки чисел (6005 и 6004) могут быть, а могут и не быть.
Вывод Я ищу-
Date/Time Num Date/Time_1 Num_1 Date/Time_2 Num_2
2023/04/10 14:13:18 6122 2023/04/10 14:14:24 6005 2023/04/10 14:14:59 6004
Если Num=6005, то дата/время и число должны быть в 3-м и 4-м столбцах, если Num=6004, то дата/время и число должны быть в 5-м и 6-м столбцах, в противном случае оставьте его пустым, как показано ниже:
Date/Time Num Date/Time_1 Num_1 Date/Time_2 Num_2
2023/04/10 14:13:18 6122 2023/04/10 14:14:59 6004
Вы можете складывать , затем конвертировать в_фрейм , транспонировать и подкачивать. Наконец, сгладьте MultiIndex:
out = df.stack().to_frame().T.swaplevel(axis=1)
out.columns = out.columns.map(lambda x: f'{x[0]}_{x[1]}')
Выход:
Date/Time_0 Num_0 Date/Time_1 Num_1 Date/Time_2 Num_2
0 2023/04/10 14:13:18 6122 2023/04/10 14:14:24 6005 2023/04/10 14:14:59 6004
Если вы не хотите _0
:
out.columns = out.columns.map(lambda x: f'{x[0]}{"_"+str(x[1]) if x[1] else ""}')
Выход:
Date/Time Num Date/Time_1 Num_1 Date/Time_2 Num_2
0 2023/04/10 14:13:18 6122 2023/04/10 14:14:24 6005 2023/04/10 14:14:59 6004
Предполагая этот ввод:
Date/Time Num
0 2023/04/10 14:13:18 6122
1 2023/04/10 14:14:59 6004
Вы можете принудительно переиндексировать с помощью словаря и переиндексировать, прежде чем применять описанный выше метод:
order = [6122, 6005, 6004]
d = {k: v for v,k in enumerate(order)}
out = (df.set_axis(df['Num'].map(d)).reindex(d.values())
.stack(dropna=False).to_frame().T.swaplevel(axis=1)
)
out.columns = out.columns.map(lambda x: f'{x[0]}{"_"+str(x[1]) if x[1] else ""}')
Выход:
Date/Time Num Date/Time_1 Num_1 Date/Time_2 Num_2
0 2023/04/10 14:13:18 6122.0 NaN NaN 2023/04/10 14:14:59 6004.0
Затем вам нужно замаскировать значения перед укладкой
Вы можете использовать numpy.ravel:
import numpy as np
cols = np.ravel([df.columns + (f'_{i}' if i else '') for i in range(len(df))])
out = pd.DataFrame([np.ravel(df)], columns=cols)
Выход:
>>> out
Date/Time Num Date/Time_1 Num_1 Date/Time_2 Num_2
0 2023/04/10 14:13:18 6122 2023/04/10 14:14:24 6005 2023/04/10 14:14:59 6004
Обновлять
Что делать, если числа 6005 нет, в этом случае он установит числовую строку 6004 в 3-м и 4-м столбцах, но я хочу, чтобы это были 5-й и 6-й столбцы, а 3-й - 4-й столбцы были пустыми?
Вы можете жестко закодировать преобразование:
pd.concat([df[df['Num'] == 6122].reset_index(drop=True),
df[df['Num'] == 6005].add_suffix('_1').reset_index(drop=True),
df[df['Num'] == 6004].add_suffix('_2').reset_index(drop=True)], axis=1)
# Output
Date/Time Num Date/Time_1 Num_1 Date/Time_2 Num_2
0 2023/04/10 14:13:18 6122 NaN NaN 2023/04/10 14:14:59 6004
Чтобы внедрить эту строку в базу данных, вы можете попытаться преобразовать NaT/NaN
в None с помощью:
# out = pd.concat(...)
out = out.replace({pd.NaT: None, np.NaN: None})
спасибо за ответ, он работает нормально, если у нас есть все три числа, то есть 6122, 6005, 6004. Что, если числа 6005 нет, в этом случае он установит числовую строку 6004 в 3-м и 4-м столбцах, но я хочу, чтобы это быть 5-й и 6-й столбцы и 3-й - 4-й столбцы будут пустыми? Обновил ответ выше
это работает нормально. Спасибо вам за быстрый ответ. Мне нужна еще одна помощь, чтобы вставить это значение в БД. У меня возникают проблемы с сохранением NaN в поле даты и времени в postgresDB. Пробовал разными способами, но ничего не получалось. Не могли бы вы предложить, как вставить NaN или пустое значение в поле даты и времени в postgres?
@RKIDEV, вы неправильно поняли, как работает этот сайт. Это не бесплатная консультационная служба, которая поможет вам решить ваши проблемы. Stackoverflow — это скорее база данных вопросов и ответов, которая должна быть полезна всем. Поэтому, пожалуйста, сосредоточьтесь на своих вопросах, придерживайтесь одной темы, не меняйте их после того, как вы получили достоверные ответы.
спасибо за ответ, он работает нормально, если у нас есть все три числа, то есть 6122, 6005, 6004. Что, если числа 6005 нет, в этом случае он установит числовую строку 6004 в 3-м и 4-м столбцах, но я хочу, чтобы это быть 5-й и 6-й столбцы и 3-й - 4-й столбцы будут пустыми? Обновил ответ выше