首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >熊猫:同一栏中的情侣分组

熊猫:同一栏中的情侣分组
EN

Stack Overflow用户
提问于 2017-11-20 12:48:49
回答 2查看 53关注 0票数 2

假设我有一个包含这些数据的表(一个dataframe):

代码语言:javascript
复制
| user     | food          |
|:--------:|:-------------:|
| 'A'      | 'meat'        | 
| 'A'      | 'carrot'      |
| 'A'      | 'candy'       |
| 'B'      |  'meat'       |
| 'B'      |  'carrot'      |
| 'C'      |  'meat'       |
| 'C'      |  'carrot'     |

代码:

代码语言:javascript
复制
df = pd.DataFrame({
    "user":["A", "A", "A", "B", "B", "C", "C"],
    "food":['meat', 'carrot', 'candy', 'meat', 'carrot', 'meat', 'carrot']
})

我想要建立的是一个表格,每一对食物告诉我有多少用户拥有它们:

代码语言:javascript
复制
| food 1     | food 2        |  num users | 
|:----------:|:-------------:|:----------:| 
| 'meat'     | 'carrot'      | 3          | 
| 'meat'     | 'candy'       | 1          | 
| 'carrot'     | 'candy'       | 1          | 

有办法这样做吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-20 13:45:58

您可以首先使用get_dummies

代码语言:javascript
复制
df = pd.get_dummies(df.set_index('user'), prefix='', prefix_sep='').max(level=0)
print (df)
      candy  carrot  meat
user                     
A         1       1     1
B         0       1     1
C         0       1     1

然后用list comprehension计数

代码语言:javascript
复制
from  itertools import combinations

L = [(x[0], x[1],(df[list(x)] == 1).all(1).sum()) for x in list(combinations(df.columns, 2))]
print (L)
[('candy', 'carrot', 1), ('candy', 'meat', 1), ('carrot', 'meat', 3)]

df = pd.DataFrame(L, columns=['food 1','food 2','num users'])
print (df)
   food 1  food 2  num users
0   candy  carrot          1
1   candy    meat          1
2  carrot    meat          3
票数 3
EN

Stack Overflow用户

发布于 2017-11-20 13:46:47

你可以试试这个:

代码语言:javascript
复制
food_pairs = [("meat", "carrot"), ("meat", "candy")]

food_to_users = {food: set(df.user[df.food == food].unique()) for food in df.food.unique()}

out = pd.DataFrame(
    ((*pair, len(set.intersection(*(food_to_users[food] for food in pair)))) for pair in food_pairs),
    columns=["food1", "food2", "num users"]
)

平均运行时间超过1000个试验是0.00256s

可伸缩性测试代码:

代码语言:javascript
复制
import itertools
import math
import pandas as pd
from random import shuffle
from timeit import time

SIZE_OF_PAIRS = 2
NUM_FOODS = 50
NUM_USERS = 1000
NUM_RECORDS = 100000

foods = (list(range(NUM_FOODS)) * (math.ceil(NUM_RECORDS/NUM_FOODS)))[:NUM_RECORDS]
users = (list(range(NUM_USERS)) * (math.ceil(NUM_RECORDS/NUM_USERS)))[:NUM_RECORDS]

shuffle(foods)
shuffle(users)

df = pd.DataFrame({"user": users, "food": foods})

food_pairs = pd.Series([*itertools.combinations(df.food.unique(), SIZE_OF_PAIRS)])

start = time.time()

food_to_users = {food: set(df.user[df.food == food].unique()) for food in df.food.unique()}
out = pd.DataFrame(
    ((*pair, len(set.intersection(*(food_to_users[food] for food in pair)))) for pair in food_pairs),
    columns=[*["food" + str(i) for i in range(SIZE_OF_PAIRS)], "num users"]
)

print("Time taken: {}s".format(time.time() - start))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47392457

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档