我有一个DF,我想按两列进行分组。我想显示的是level = 1中每个项目(例如“ c”)在level = 0中每个项目的总和的百分比(在下面的示例中,即“ a”和“ b”的总和)的百分比,在示例中为“ d”,“ e”)。
示例:
我有以下数据框
def ineffectiveScale(self):
ws = Window.size
part = 600
whole = ws[1]
dif = whole-part
percent = 100 * float(dif)/float(whole)
if ws[1] <= 1000:
self.size = 0.7+(percent * 0.8) / 100.0
elif ws[1] >= 1000 and ws[1] <= 2000:
self.size = 1.1+(percent * 1.2) / 100.0
elif ws[1] >= 2000 and ws[1] <= 3000:
self.size = 1.6+(percent * 1.7) / 100.0
elif ws[1] >= 3000 and ws[1] <= 4000:
self.size = 2.0+(percent * 2.1) / 100.0
elif ws[1] >= 4000:
self.size = 2.5+(percent * 2.6) / 100.0
我想获得这个:
from __future__ import division
from collections import namedtuple
import json
import math
import random
from kivy import platform
from kivy.app import App
from kivy.base import EventLoop
from kivy.clock import Clock
from kivy.core.image import Image
from kivy.core.window import Window
from kivy.graphics import Mesh
from kivy.graphics.instructions import RenderContext
from kivy.uix.widget import Widget
from kivy.utils import get_color_from_hex
import base64
UVMapping = namedtuple('UVMapping', 'u0 v0 u1 v1 su sv')
GLSL = """
---vertex
$HEADER$
attribute vec2 vCenter;
attribute float vScale;
void main(void)
{
tex_coord0 = vTexCoords0;
mat4 move_mat = mat4
(1.0, 0.0, 0.0, vCenter.x,
0.0, 1.0, 0.0, vCenter.y,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0);
vec4 pos = vec4(vPosition.xy * vScale, 0.0, 1.0)
* move_mat;
gl_Position = projection_mat * modelview_mat * pos;
}
---fragment
$HEADER$
void main(void)
{
gl_FragColor = texture2D(texture0, tex_coord0);
}
"""
with open("game.glsl", "w") as wr:
wr.write(GLSL)
def load_atlas():
atlas = json.loads('''{"img.png": {"Elien": [2, 26, 100, 100]}}''')
tex_name, mapping = atlas.popitem()
data = '''iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAACJklEQVR4nO3dy1ICQRAF0YLw/39ZVxMBGCjEMF23JvOsXPgounMaN61VQrtsH3x3TqFfLv9/ykdcq9z8RKv25Lro5yiUAcAZAJwBwBkAnAHAGQCcAcAZAJwBwBkAnAHAGQCcAcAZAJwBwBkAnAHAGQCcAcAZAJwBwBkAnAHAfXUPsNM79ydWXbYZZVoAey7MPH6tQdScAI64KbV9T3QI6QGsuCKHDiH5l8DVd1aRd2QTT4DOjcCdBmknQMpTmDLH4ZICSFv0tHkOkRJA6mKnzvUxCQGkL3L6fLskBKBG3QFMebqmzPm2zgCmLeq0eV/SfQKoWVcAU5+mqXM/5QkA1xHA9Kdo+vx3PAHgDADOAOBWB3CW98+zvA5PADoDgDMAOAOAMwA4A4AzADgDgDMAuNUBnOXCxVlehycAnQHAGQBcRwDT3z+nz3/HEwCuK4CpT9HUuZ/yBIDrDGDa0zRt3pd0nwBTFnXKnG/rDkDNEgJIf7rS59slIYCq3EVOnetjUgKoylvstHkOkRRAVc6ip8xxuMS/E7gtfsflC8zGb9JOgFurNwO3+VWZJ8CtFacBcuM36QFsjggBvfGbKQFsHjfNfxix07QAHrmpOyX/EqgFDADOAOAMAM4A4AwAzgDgDADOAOAMAM4A4AwAzgDgDADOAOAMAM4A4AwAzgDgDADOAOAMAM4A4AwA7lrl7YpE7okkSZIkSZIkSZIkSZIkSZIkSZL+9AMvSSThyPfOhQAAAABJRU5ErkJggg=='''
with open(tex_name, "wb") as co:
co.write(base64.b64decode(data))
tex = Image(tex_name).texture
tex_width, tex_height = tex.size
uvmap = {}
for name, val in mapping.items():
x0, y0, w, h = val
x1, y1 = x0 + w, y0 + h
uvmap[name] = UVMapping(
x0 / tex_width, 1 - y1 / tex_height,
x1 / tex_width, 1 - y0 / tex_height,
0.5 * w, 0.5 * h)
return tex, uvmap
class Particle:
x = 0
y = 0
size = 1
def __init__(self, parent, i):
self.parent = parent
self.vsize = parent.vsize
self.base_i = 4 * i * self.vsize
self.reset(created=True)
def update(self):
for i in range(self.base_i,
self.base_i + 4 * self.vsize,
self.vsize):
self.parent.vertices[i:i + 3] = (
self.x, self.y, self.size)
def reset(self, created=False):
raise NotImplementedError()
def advance(self, nap):
raise NotImplementedError()
class GameScreen(Widget):
indices = []
vertices = []
particles = []
def __init__(self, **kwargs):
Widget.__init__(self, **kwargs)
self.canvas = RenderContext(use_parent_projection=True)
self.canvas.shader.source = "game.glsl"
self.vfmt = (
(b'vCenter', 2, 'float'),
(b'vScale', 1, 'float'),
(b'vPosition', 2, 'float'),
(b'vTexCoords0', 2, 'float'),
)
self.vsize = sum(attr[1] for attr in self.vfmt)
self.texture, self.uvmap = load_atlas()
def make_particles(self, Ap, num):
count = len(self.particles)
uv = self.uvmap[Ap.tex_name]
for i in range(count, count + num):
j = 4 * i
self.indices.extend((
j, j + 1, j + 2, j + 2, j + 3, j))
self.vertices.extend((
0, 0, 1, -uv.su, -uv.sv, uv.u0, uv.v1,
0, 0, 1, uv.su, -uv.sv, uv.u1, uv.v1,
0, 0, 1, uv.su, uv.sv, uv.u1, uv.v0,
0, 0, 1, -uv.su, uv.sv, uv.u0, uv.v0,
))
p = Ap(self, i)
self.particles.append(p)
def update_glsl(self, nap):
for p in self.particles:
p.advance(nap)
p.update()
self.canvas.clear()
with self.canvas:
Mesh(fmt=self.vfmt, mode='triangles',
indices=self.indices, vertices=self.vertices,
texture=self.texture)
class ScaleTest(Particle):
tex_name = 'Elien'
texture_size = 129
def reset(self, created=False):
self.x = random.randint(15, self.parent.right-15)
self.y = random.uniform(-100, -2500)
self.size = 1 #FULL SIZE BEFORE RESIZED
self.ineffectiveScale() #Comment this line to see the problem of large resolution screens
def ineffectiveScale(self):
ws = Window.size
part = 600
whole = ws[1]
dif = whole-part
percent = 100 * float(dif)/float(whole)
if ws[1] <= 1000:
self.size = 0.7+(percent * 0.8) / 100.0
elif ws[1] >= 1000 and ws[1] <= 2000:
self.size = 1.1+(percent * 1.2) / 100.0
elif ws[1] >= 2000 and ws[1] <= 3000:
self.size = 1.6+(percent * 1.7) / 100.0
elif ws[1] >= 3000 and ws[1] <= 4000:
self.size = 2.0+(percent * 2.1) / 100.0
elif ws[1] >= 4000:
self.size = 2.5+(percent * 2.6) / 100.0
def advance(self, nap):
self.y += 100 * 2 * nap
if self.y > self.parent.top:
self.reset()
class Game(GameScreen):
def initialize(self):
self.make_particles(ScaleTest, 20)
def update_glsl(self, nap):
GameScreen.update_glsl(self, nap)
class GameApp(App):
def build(self):
EventLoop.ensure_window()
return Game()
def on_start(self):
self.root.initialize()
Clock.schedule_interval(self.root.update_glsl, 60 ** -1)
if __name__ == '__main__':
Window.clearcolor = get_color_from_hex('111110')
GameApp().run()
答案 0 :(得分:3)
首先将sum
按两列进行汇总,然后按sum
的第一级除以DataFrame.div
MultiIndex
:
df1 = df.groupby(['col1','col2']).sum()
df1 = df1.div(df1.sum(level=0), level=0)
print (df1)
col3
col1 col2
a c 0.4
d 0.4
e 0.2
b c 0.4
d 0.4
e 0.2