使用条件从单独的数据框中计算行 - PySpark

Count Rows from a separate dataframe with conditions - PySpark

我有一个航空公司预订交易数据框,其列为 customer_id, date_of_travel, dest_country。我有另一个数据框,其中包含 customer_id, date_of_booking, dest_country.

的酒店预订交易详细信息

我需要在航空公司预订数据框中添加一个列,该列将计算 customer_id 在同一国家/地区 1 个月(+/- 30 天)内为该 customer_id 进行的所有酒店预订16=].

我在 Date_before_30_Days 和 Date_after_30_Days 的航空公司预订数据集中添加了 2 个额外的列。我无法理解如何获得在同一国家/地区乘坐飞机旅行 1 个月内的酒店预订数量。

航空公司数据

Customer_id Country     Date_of_Travel
xyz     US      10-20-2018
abc     MX      03-04-2018
xyz     US      04-05-2019

酒店数据

Customer_id Country     Date_of_Booking
xyz     CA      03-30-2018
xyz     US      05-01-2018
xyz     US      10-15-2018
abc     PH      10-20-2018
abc     MX      03-01-2018

最终输出

Customer_id Country     Date_of_Travel      Total_Hotel_Bookings
xyz     US      10-20-2018          1
abc     MX      03-04-2018          0
xyz     CA      04-05-2019          1

对于 airline_data 的每一行,您必须在 hotel_data:

中创建过滤器
filter_id = hotel_data[Customer_id] == desired_id
filter_country = hotel_data[Country] == desired_country
filter_date = (hotel_data[Date_of_Booking] > start_date) & (hotel_data[Date_of_Booking] < end_date)

然后应用过滤器并计算结果:

filtered_df = hotel_data[filter_id & filter_country & filter_date]
total_bookings = len(filtered_df)

当然,您可以使用循环执行此操作并将预订数量添加到列表中,最后只需将列表添加为 airline_data.

的新列

这有帮助吗?

您提供的示例的输出与您在声明中提到的不同。例如)根据航空公司数据,客户 ID "abc" in "MX" 国家实际上在 1st March 上预订了酒店,他还在 4th March 上预订了机票。这实际上落在 (+/-) 30 天范围内。

通过理解你的陈述,我做了下面的例子。

航空公司数据

airline_data = pd.DataFrame({"Customer_Id":["xyz", "abc", "xyz"], "Country":["US", "MX", "CA"],"Date_Of_Travel":["10-20-2018", "03-04-2018", "04-05-2019"]})

print(airline_data)

Customer_Id Country Date_Of_Travel
xyz         US      10-20-2018
abc         MX      03-04-2018
xyz         CA      04-05-2019

酒店数据

Hotel_data = pd.DataFrame({"Customer_Id":["xyz","xyz", "xyz","abc", "abc"], "Country":["CA","US","US","PH","MX"],"Date_of_Booking":["03-30-2019", "05-01-2018", "10-15-2018", "10-20-2018", "03-01-2018"]})

print(Hotel_data)

Customer_Id Country Date_of_Booking
xyz         CA      03-30-2019
xyz         US      05-01-2018
xyz         US      10-15-2018
abc         PH      10-20-2018
abc         MX      03-01-2018

将日期列从字符串转换为日期时间对象

airline_data["Date_Of_Travel"] = pd.to_datetime(airline_data["Date_Of_Travel"])
Hotel_data["Date_of_Booking"] = pd.to_datetime(Hotel_data["Date_of_Booking"])

为最小日期和最大日期创建两列,即 (+/-) 30 天。

airline_data["Min_date"] = (airline_data["Date_Of_Travel"]) - pd.Timedelta(days=30)
airline_data["Max_date"] = (airline_data["Date_Of_Travel"]) + pd.Timedelta(days=30)

根据Customer_id、国家/地区加入两个数据框以获得所需数据

df_1 = pd.merge(airline_data, Hotel_data, on=["Customer_Id", "Country"],how="left")

print(df_1)


Customer_Id Country Date_Of_Travel  Min_date    Max_date    Date_of_Booking
xyz         US      2018-10-20      2018-09-20  2018-11-19  2018-05-01
xyz         US      2018-10-20      2018-09-20  2018-11-19  2018-10-15
abc         MX      2018-03-04      2018-02-02  2018-04-03  2018-03-01
xyz         CA      2019-04-05      2019-03-06  2019-05-05  2019-03-30

创建满足预订条件的列是从旅行日期起 +/- 30 天。

df_1["Bool"] = (df_1.Date_of_Booking >= df_1.Min_date) & (df_1.Date_of_Booking <= df_1.Max_date)

df_1["Bool"] = df_1["Bool"].apply(int)

print(df_1)


Customer_Id Country Date_Of_Travel  Min_date    Max_date    Date_of_Booking Bool
xyz         US      2018-10-20      2018-09-20  2018-11-19  2018-05-01      0
xyz         US      2018-10-20      2018-09-20  2018-11-19  2018-10-15      1
abc         MX      2018-03-04      2018-02-02  2018-04-03  2018-03-01      1
xyz         CA      2019-04-05      2019-03-06  2019-05-05  2019-03-30      1

现在,在 df_1 上应用 groupby 并获取布尔值的总和以获得特定国家/地区每个客户的总预订量。

Req_Results = df_1.groupby(["Customer_Id","Country","Date_Of_Travel","Date_of_Booking"]).sum().reset_index()

Req_Results = Req_Results[Req_Results.Bool!=0]

Req_Results.rename(columns={"Bool":"Total_Hotel_Bookings"},inplace=True)

print(Req_Results)


Customer_Id Country Date_Of_Travel  Date_of_Booking   Total_Hotel_Bookings
abc        MX       2018-03-04      2018-03-01           1
xyz        CA       2019-04-05      2019-03-30           1
xyz        US       2018-10-20      2018-10-15           1