Создайте функцию для объединения строк в Python

У меня есть Pandas df, как определено ниже:

    ID     Start          End
0   77     2018-07-02    2020-07-02
1   88     2019-07-02    2021-07-02
2   99     2020-07-02    2022-07-02

Я хочу создать функцию для возврата следующего результата (строки):

((Date BETWEEN '2018-07-02' AND '2020-07-02') AND ID = 77)
OR ((Date BETWEEN '2019-07-02' AND '2021-07-02') AND ID = 88)
OR ((Date BETWEEN '2020-07-02' AND '2022-07-02') AND ID = 99)

Вот что я написал, но это не дало ожидаемого результата:

def create_string(df):
    date_start = df.loc[
       (df['ID'] == ID), 'Start']
    date_end = df.loc[
       (df['ID'] == ID), 'End']
    date_string = F"(((Date BETWEEN '{date_start}' AND '{date_end}') AND ID = '{ID}') OR"
    string = ""
    final_string = string + date_string
    return final_string

IDs = df.ID.copy()

for ID in IDs:
    print(create_string(df))

Любые предложения будут ценны!

Почему в 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
0
55
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

ты можешь сделать вот так

df["cond"] = df.apply(lambda r: f"((Date BETWEEN '{r['start']}' AND 'r['end']') AND ID = r['ID'])", axis=1)

тогда исходящая строка может быть рассчитана с помощью

final_str = " OR ".join(df["cond"].tolist())

Спасибо @Xiaomin. Добавьте фигурные скобки к r['end'] и r['ID'], тогда ваш код будет работать хорошо.

Shichimi 08.07.2023 22:02

Получил рабочий пример:

import pandas as pd

d = {'ID': [77,78,99], 'Start': ['2018-07-02', '2018-07-03', '2018-07-04'], 
     'End': ['2018-07-05', '2018-07-06', '2018-07-07']}


df = pd.DataFrame(data=d)

def create_string(df, id_, string):
    date_start = df.loc[df['ID'] == id_].iloc[0,1]
    date_end = df.loc[df['ID'] == id_].iloc[0,2]
    date_string = F"(((Date BETWEEN '{date_start}' AND '{date_end}') AND ID = '{id_}') OR"
    string += date_string
    return string


string = ""
for id_ in [77, 78,99]:
    string = create_string(df,id_, string)
print(string)

Ваши проблемы были:

  • некоторые ошибки индексации при выборе фрейма данных.
  • переопределение строки каждый раз в функции
  • функция не возвращает новое строковое значение

Спасибо @matleg. Смотрите ошибку моего кода. Да, ты прав. Строка каждый раз переопределяется в функции.

Shichimi 08.07.2023 21:45

Вы почти там. Вам просто нужно вызвать values[0] при доступе к датам и внести небольшие изменения в параметры функции.

def create_string(df, ID):
    date_start = df.loc[
       (df['ID'] == ID), 'Start'].values[0]
    date_end = df.loc[
       (df['ID'] == ID), 'End'].values[0]
    date_string = f"((Date BETWEEN '{date_start}' AND '{date_end}') AND ID = {ID})"
    return date_string
    

IDs = df.ID.copy()
strings = []

for ID in IDs:
    strings.append(create_string(df, ID))

print(" OR\n".join(strings))

В качестве альтернативы вы можете написать это таким образом. Это делает ваш код намного чище.


def get_dates(df, ID):
    date_start = df.loc[df['ID'] == ID, 'Start'].values[0]
    date_end = df.loc[df['ID'] == ID, 'End'].values[0]
    return date_start, date_end

def create_date_string(df, ID):
    date_start, date_end = get_dates(df, ID)
    date_string = f"((Date BETWEEN '{date_start}' AND '{date_end}') AND ID = {ID})"
    return date_string

def create_all_strings(df):
    IDs = df.ID.copy()
    all_strings = [create_date_string(df, ID) for ID in IDs]
    return " OR\n".join(all_strings)

print(create_all_strings(df))

Спасибо @Нил. Ваше второе решение лаконично!

Shichimi 08.07.2023 21:47
Ответ принят как подходящий

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

' OR '.join(map(lambda r: "(DATE BETWEEN '{}' AND '{}' AND ID = {})".format(r[1], r[2], r[0]), df.values.tolist()))

Выход:

"(DATE BETWEEN '2018-07-02' AND '2020-07-02' AND ID = 77) OR (DATE BETWEEN '2019-07-02' AND '2021-07-02' AND ID = 88) OR (DATE BETWEEN '2020-07-02' AND '2022-07-02' AND ID = 99)"

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