重组大熊猫中的无关数据

时间:2017-08-02 21:48:51

标签: python pandas dataframe pivot

我有一个像这样组织的数据框......

**Name** | **Mealtime** | **Food**  
John | 8:00 am | cereal  
John | 1:00 pm | salad  
John | 6:00 pm | pasta  
Sara | 8:00 am | yogurt  
Sara | 1:00 pm | panini  
Sara | 6:00 pm | steak  
Jake | 8:00 am | coffee  
Jake | 1:00 pm | burrito  
Jake | 6:00 pm | salad

我需要像这样组织它

____| 8:00 am | 1:00 pm | 6:00 pm  
John | cereal | salad | pasta  
Sara | yogurt | panini | steak  
Jake | coffee | burrito | salad

我该怎么做呢?请注意,我不是在寻找美学上的改变。最后,我想选择一行数据来输入for循环,这样可以从特定的食物条目中确定名称。例如,抓住了下午1点"专栏,"沙拉"我会指引约翰。但如果我抓住了下午6点和#34;专栏,"沙拉"会引导我去杰克。

2 个答案:

答案 0 :(得分:4)

您需要df.pivot

In [606]: df.pivot(index='Name', columns='Mealtime', values='Food')
Out[606]: 
Mealtime  1:00 pm 6:00 pm 8:00 am
Name                             
Jake      burrito   salad  coffee
John        salad   pasta  cereal
Sara       panini   steak  yogurt

答案 1 :(得分:3)

选项0
numpy切片pd.factorize

我将使用pd.factorize为每个唯一'Name''Mealtime'生成整数值。除此之外,我也获得了独特的价值观。每个整数值最终对应于唯一值数组中该整数位置中的元素。

现在我知道了唯一名字的数量和独特的用餐时间,所以我知道我最终的旋转阵列的大小。所以我创建一个空的,等待分配值。

由于我将因子分解并且因子是整数位置,我可以使用它们来分配我的空数组以用于分配目的......所以我这样做。最后,我总结了一个新的闪亮数据框。

fn, un = pd.factorize(df.Name.values)
fm, um = pd.factorize(df.Mealtime.values)
v = np.empty((un.size, um.size), dtype=object)
v[fn, fm] = df.Food.values
pd.DataFrame(v, un, um)

     8:00 am  1:00 pm 6:00 pm
John  cereal    salad   pasta
Sara  yogurt   panini   steak
Jake  coffee  burrito   salad

选项1
使用set_index / unstack

df.set_index(['Name', 'Mealtime']).Food.unstack()

Mealtime  1:00 pm 6:00 pm 8:00 am
Name                             
Jake      burrito   salad  coffee
John        salad   pasta  cereal
Sara       panini   steak  yogurt

选项2
使用defaultdict

from collections import defaultdict

d = defaultdict(dict)
[d[m].setdefault(n, f) for n, m, f in df.values];
pd.DataFrame(d)

      1:00 pm 6:00 pm 8:00 am
Jake  burrito   salad  coffee
John    salad   pasta  cereal
Sara   panini   steak  yogurt

选项3
蛮力

out = pd.DataFrame(index=df.Name.unique(), columns=df.Mealtime.unique())
[out.set_value(n, m, f) for n, m, f in df.values]
out

     8:00 am  1:00 pm 6:00 pm
John  cereal    salad   pasta
Sara  yogurt   panini   steak
Jake  coffee  burrito   salad

<强>时序
结论:对纯大熊猫使用pivot来获取更大的数据。在这种情况下难以击败其简单性和完成工作的能力。但如果你想以鲁莽的速度转动,请尝试选项0

%%timeit
fn, un = pd.factorize(df.Name.values)
fm, um = pd.factorize(df.Mealtime.values)
v = np.empty((un.size, um.size), dtype=object)
v[fn, fm] = df.Food.values
pd.DataFrame(v, un, um)

%timeit df.set_index(['Name', 'Mealtime']).Food.unstack()
%timeit df.pivot('Name', 'Mealtime', 'Food')
%timeit d = defaultdict(dict); [d[m].setdefault(n, f) for n, m, f in df.values]; pd.DataFrame(d)
%timeit out = pd.DataFrame(index=df.Name.unique(), columns=df.Mealtime.unique()); [out.set_value(n, m, f) for n, m, f in df.values]; out

小数据

1000 loops, best of 3: 300 µs per loop
1000 loops, best of 3: 1.82 ms per loop
1000 loops, best of 3: 1.11 ms per loop
1000 loops, best of 3: 541 µs per loop
1000 loops, best of 3: 656 µs per loop

更大的数据

from string import ascii_letters

foods = np.array([
    'cereal', 'salad', 'pasta', 'yogurt',
    'panini', 'steak', 'coffee', 'burrito'
], dtype=object)
times = pd.date_range(
    pd.datetime.now().date(), periods=24, freq='H'
).strftime('%-I:00 %p')
names = list(ascii_letters)

idx = pd.MultiIndex.from_product([names, times], names=['Name', 'Mealtime'])
df = pd.DataFrame(dict(
    Food=np.random.choice(foods, idx.size),
), idx).reset_index()

1000 loops, best of 3: 383 µs per loop
1000 loops, best of 3: 1.99 ms per loop
1000 loops, best of 3: 1.34 ms per loop
100 loops, best of 3: 2.78 ms per loop
100 loops, best of 3: 6.6 ms per loop