選項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
使用/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
尼斯......計劃包括一個大型數據集的測試? –
你走了... – piRSquared
defaultdict方法比我想象的要好!讓我印象深刻。 –