如何创建非空DataFrame?酒店推荐算法空DataFrame问题排查
问题排查:酒店推荐算法生成空DataFrame的问题
问题描述
我在用一套酒店推荐算法,文本输出符合预期,但把推荐酒店列表和其他酒店列表转换为对应DataFrame时,始终得到空DataFrame。需要将这两类酒店数据分别存入独立的DataFrame,请求协助排查问题。
代码实现
import pandas as pd def recommend_hotels(data, weights): df = pd.DataFrame(data) # Ask the user for the passenger count passenger_count = int(input("Enter the number of passengers: ")) # Calculate the minimum number of rooms needed min_rooms_needed = passenger_count # Calculate the difference between total room availability and the passenger count df['room_diff'] = df['total_rooms'] - min_rooms_needed # Filter hotels with higher availability than the passenger count and sort by room availability in ascending order df = df[df['room_diff'] >= 0].sort_values(by='total_rooms') # If there are no hotels with higher availability, sort by room availability in ascending order if df.empty: df = data.copy() df = df.sort_values(by='total_rooms') # Initialize variables to track room assignments assigned_rooms = [] remaining_passengers = passenger_count # Assign double rooms first for index, row in df.iterrows(): double_rooms_available = row['double_rooms'] if double_rooms_available > 0: assigned_double_rooms = min(double_rooms_available, remaining_passengers // 2) remaining_passengers -= assigned_double_rooms * 2 assigned_rooms.append((row['hotel_name'], assigned_double_rooms, 'double')) # Assign single rooms if needed for index, row in df.iterrows(): if remaining_passengers > 0: single_rooms_available = row['single_rooms'] assigned_single_rooms = min(single_rooms_available, remaining_passengers) remaining_passengers -= assigned_single_rooms assigned_rooms.append((row['hotel_name'], assigned_single_rooms, 'single')) # Recommend hotels based on room assignments recommended_hotels = [hotel[0] for hotel in assigned_rooms] # Calculate the total number of rooms to book for all passengers total_rooms_to_book = min_rooms_needed # Create a DataFrame for recommended hotels recommended_hotels_df = df[df['hotel_name'].isin(recommended_hotels)].sort_values(by='total_rooms', ascending=False) recommended_hotels_df # Print the initial recommendations print(f"Recommended Hotels: {', '.join(recommended_hotels)}") print(f"Book {total_rooms_to_book} rooms for {passenger_count} passengers.") # List unrecommended hotels in descending order of room availability unrecommended_hotels = set(data['hotel_name']) - set(recommended_hotels) if unrecommended_hotels: unrecommended_df = df[df['hotel_name'].isin(unrecommended_hotels)].sort_values(by='total_rooms', ascending=False) #print(f"\nUnrecommended Hotels (Not in Recommended List) in Descending Order of Availability:") for index, row in unrecommended_df.iterrows(): print(f"{row['hotel_name']} - Total Rooms: {row['total_rooms']}") # List all other hotels that are not in the recommended list other_hotels = set(data['hotel_name']) - set(recommended_hotels) print(f"\nAll Other Hotels (Not in Recommended List): {', '.join(other_hotels)}") # Create a DataFrame for all other hotels that are not in the recommended list other_hotels_df = df[df['hotel_name'].isin(other_hotels)] # Define your data and weights data = { 'hotel_name': ['A', 'B', 'C', 'D', 'E'], 'single_rooms': [10, 25, 8, 12, 7], 'double_rooms': [35, 18, 44, 110, 6], 'total_rooms': [45, 43, 52, 122, 13], } weights = { 'num_hotels': 0.35, 'transport': 0.3, 'room_price': 0.15, 'meals': 0.1, 'availability': 0.075, 'rooms': 0.025, } other_hotels_df # Call the recommend_hotels function with your data and weights recommend_hotels(data, weights)
当前输出
输出显示空DataFrame,无有效数据。
尝试的代码
other_hotels = set(data['hotel_name']) - set(recommended_hotels) other_hotels_df =df[df['hotel_name'].isin(other_hotels)].sort_values(by='total_rooms', ascending=False)
期望输出
Recommended_df:
| hotel_name | single_rooms | double_rooms | total_rooms |
|---|---|---|---|
| B | 25 | 18 | 43 |
| A | 10 | 35 | 45 |
| C | 8 | 44 | 52 |
| D | 12 | 110 | 122 |
UnRecommended_df:
| hotel_name | single_rooms | double_rooms | total_rooms |
|---|---|---|---|
| E | 7 | 6 | 13 |
问题根源与修复方案
1. 核心问题
- 缩进错误导致变量作用域异常:
recommended_hotels的定义被错误缩进,属于第二个for循环的内部代码,仅在循环满足条件时才会赋值,导致变量可能未定义或为空。 - DataFrame赋值语法错误:
recommended_hotels_df的定义存在换行错误,无法正确初始化。 - 过滤后的数据丢失问题:当通过
df = df[df['room_diff'] >= 0]过滤酒店后,部分酒店(如E)被排除在当前df之外,后续用该df筛选非推荐酒店时无法找到对应数据。 - 无返回值:函数内创建的DataFrame未返回,外部无法获取结果。
2. 修复后的完整代码
import pandas as pd def recommend_hotels(data, weights): # 保存原始数据的DataFrame,避免过滤后丢失数据 df_raw = pd.DataFrame(data) df = df_raw.copy() # 获取乘客数量 passenger_count = int(input("Enter the number of passengers: ")) min_rooms_needed = passenger_count # 计算房间余量 df['room_diff'] = df['total_rooms'] - min_rooms_needed # 过滤可用房间足够的酒店并排序 df = df[df['room_diff'] >= 0].sort_values(by='total_rooms') # 无满足条件的酒店时,使用原始数据排序 if df.empty: df = df_raw.copy().sort_values(by='total_rooms') assigned_rooms = [] remaining_passengers = passenger_count # 优先分配双人间 for index, row in df.iterrows(): double_rooms_available = row['double_rooms'] if double_rooms_available > 0: assigned_double_rooms = min(double_rooms_available, remaining_passengers // 2) remaining_passengers -= assigned_double_rooms * 2 assigned_rooms.append((row['hotel_name'], assigned_double_rooms, 'double')) # 分配单人间补全 for index, row in df.iterrows(): if remaining_passengers <= 0: break single_rooms_available = row['single_rooms'] assigned_single_rooms = min(single_rooms_available, remaining_passengers) remaining_passengers -= assigned_single_rooms assigned_rooms.append((row['hotel_name'], assigned_single_rooms, 'single')) # 提取推荐酒店列表(修正缩进,确保全局作用域) recommended_hotels = [hotel[0] for hotel in assigned_rooms] total_rooms_to_book = min_rooms_needed # 基于原始DataFrame创建推荐/非推荐DataFrame recommended_hotels_df = df_raw[df_raw['hotel_name'].isin(recommended_hotels)].sort_values(by='total_rooms', ascending=False) unrecommended_hotels = set(data['hotel_name']) - set(recommended_hotels) unrecommended_df = df_raw[df_raw['hotel_name'].isin(unrecommended_hotels)].sort_values(by='total_rooms', ascending=False) # 打印输出 print(f"Recommended Hotels: {', '.join(recommended_hotels)}") print(f"Book {total_rooms_to_book} rooms for {passenger_count} passengers.") if unrecommended_hotels: print(f"\nUnrecommended Hotels (Not in Recommended List) in Descending Order of Availability:") for index, row in unrecommended_df.iterrows(): print(f"{row['hotel_name']} - Total Rooms: {row['total_rooms']}") print(f"\nAll Other Hotels (Not in Recommended List): {', '.join(unrecommended_hotels)}") # 返回两个DataFrame return recommended_hotels_df, unrecommended_df # 定义数据与权重 data = { 'hotel_name': ['A', 'B', 'C', 'D', 'E'], 'single_rooms': [10, 25, 8, 12, 7], 'double_rooms': [35, 18, 44, 110, 6], 'total_rooms': [45, 43, 52, 122, 13], } weights = { 'num_hotels': 0.35, 'transport': 0.3, 'room_price': 0.15, 'meals': 0.1, 'availability': 0.075, 'rooms': 0.025, } # 调用函数并获取结果 recommended_df, unrecommended_df = recommend_hotels(data, weights) print("\nRecommended_df:") print(recommended_df) print("\nUnRecommended_df:") print(unrecommended_df)
3. 修复要点说明
- 新增
df_raw保存原始数据,避免过滤后丢失非推荐酒店的信息。 - 修正
recommended_hotels的缩进,确保变量在全局作用域内正确赋值。 - 修复
recommended_hotels_df的语法错误,基于原始DataFrame筛选数据。 - 函数返回两个DataFrame,外部可以直接获取结果。
- 在单人间分配循环中增加
break条件,优化性能。
内容的提问来源于stack exchange,提问作者Noob Coder
相关产品推荐
相关产品推荐

