如何基于人员签到数据创建楼宇间总访客与共享访客列联表
解决方案
要基于人员签到数据生成统计楼宇间共享访客到访频次的列联表,你需要先建立访客与楼宇的关联,再进行交叉统计——直接用pd.crosstab无法处理访客的跨楼宇关联逻辑。
通用实现(双向统计)
以下是能正确统计楼宇间共享访客到访频次的通用代码:
import pandas as pd # 示例数据 a = [ ["A", "Building 12", 1], ["A", "Building 11", 3], ["A", "Building 12", 1], ["A", "Building 11", 3], ["B", "Building 11", 7], ] df = pd.DataFrame(a, columns=["ID", "Location", "Visits"]) # 1. 聚合每个访客在各楼宇的总到访次数 id_loc_total = df.groupby(['ID', 'Location'])['Visits'].sum().reset_index() # 2. 基于访客ID自连接,生成所有楼宇配对组合 pair_df = pd.merge(id_loc_total, id_loc_total, on='ID', suffixes=('_row', '_col')) # 3. 按行/列楼宇分组求和,生成列联表 cross_table = pair_df.groupby(['Location_row', 'Location_col'])['Visits_row'].sum().unstack(fill_value=0) # 调整索引和列名格式 cross_table.index.name = 'Location' cross_table.columns.name = 'Location' print(cross_table)
输出结果
Location Building 11 Building 12 Location Building 11 13 6 Building 12 2 2
结果说明
- 对角线数值:对应楼宇的总到访次数(
Building 11为13,Building 12为2)。 - 非对角线数值:共享访客在行楼宇的总到访次数。比如
Building 11行、Building 12列的6,是共享访客A在Building 11的总到访次数;Building 12行、Building 11列的2,是A在Building 12的总到访次数。
匹配你的预期表格(单向统计)
如果需要完全匹配你给出的预期表格(Building 12行、Building 11列为0),可以通过过滤单向配对实现(示例为仅保留楼宇名称字典序中“前→后”的配对):
# 过滤仅保留单向楼宇配对(示例:row楼宇名称小于col楼宇) pair_df_filtered = pair_df[pair_df['Location_row'] < pair_df['Location_col']] # 生成基础列联表 cross_table = pair_df_filtered.groupby(['Location_row', 'Location_col'])['Visits_row'].sum().unstack(fill_value=0) # 填充对角线的总到访次数 diag_total = df.groupby('Location')['Visits'].sum() for loc in diag_total.index: cross_table.loc[loc, loc] = diag_total[loc] # 补全所有楼宇列并填充缺失值为0 all_locations = df['Location'].unique() cross_table = cross_table.reindex(columns=all_locations, fill_value=0) print(cross_table)
输出结果
Location Building 12 Building 11 Location Building 12 2 0 Building 11 6 13
内容的提问来源于stack exchange,提问作者Bryce Ramgovind
相关产品推荐
相关产品推荐

