Probably the fastest solution using broadcast numpy
is
i = np.arange(1, df.Value.max() + 1)
j = df.Value.values[:, None] >= i
df = pd.DataFrame(j, columns=i, index=df.Name).sum(level=0)
1 2 3 4 5
Name
x 4.0 4.0 3.0 1.0 1.0
y 2.0 2.0 1.0 0.0 0.0
z 1.0 1.0 1.0 1.0 0.0
Warning. In exchange for performance, this is a somewhat hungry method. For big data, this can lead to memory exiting, so use it with discretion.
More details
Create a range of values ββfrom 1
to df.Value.max()
-
i = np.arange(1, df.Value.max() + 1)
i
array([1, 2, 3, 4, 5])
df.Values
i
-
j = df.Value.values[:, None] >= i
j
array([[ True, True, True, True, True],
[ True, True, False, False, False],
[ True, True, True, False, False],
[ True, True, True, False, False],
[ True, True, True, False, False],
[ True, True, False, False, False],
[ True, True, True, True, False]], dtype=bool)
df.Name
, .
k = pd.DataFrame(j, columns=i, index=df.Name)
k
1 2 3 4 5
Name
x True True True True True
x True True False False False
x True True True False False
x True True True False False
y True True True False False
y True True False False False
z True True True True False
k.sum(level=0)
1 2 3 4 5
Name
x 4.0 4.0 3.0 1.0 1.0
y 2.0 2.0 1.0 0.0 0.0
z 1.0 1.0 1.0 1.0 0.0
, .astype(int)
-
k.sum(level=0).astype(int)
1 2 3 4 5
Name
x 4 4 3 1 1
y 2 2 1 0 0
z 1 1 1 1 0