আমি মনে করি এটির জন্য বেঞ্চমার্কিং দরকার। ওপির আসল ডেটা ফ্রেম ব্যবহার করে,
df = pd.DataFrame({
'state': ['CA', 'WA', 'CO', 'AZ'] * 3,
'office_id': range(1, 7) * 2,
'sales': [np.random.randint(100000, 999999) for _ in range(12)]
})
তার উত্তরে মন্তব্য করা হিসাবে, অ্যান্ডি ভেক্টরিকরণ এবং পান্ডাস সূচকের সম্পূর্ণ সুবিধা গ্রহণ করে।
c = df.groupby(['state', 'office_id'])['sales'].sum().rename("count")
c / c.groupby(level=0).sum()
প্রতি লুপে 3.42 এমএস ± 16.7 µ গুলি
(7 of রানের গড় ± স্ট্যান্ড। ডিভ। প্রতি 100 টি লুপ)
state_office = df.groupby(['state', 'office_id']).agg({'sales': 'sum'})
state = df.groupby(['state']).agg({'sales': 'sum'})
state_office.div(state, level='state') * 100
প্রতি লুপে 4.66 এমএস .4 24.4
(গুলি (7 7 রানের গড় ± দশমিক দেব, প্রতিটি 100 লুপ)
এটি স্তরের 0 হিসাবে x.sum()
প্রতিটি হিসাবে গণনা করা এটি সবচেয়ে ধীর উত্তর x
।
আমার জন্য, এটি এখনও একটি দরকারী উত্তর, যদিও এটি বর্তমান আকারে নেই। ছোট ডেটাসেটে দ্রুত ইডিএর জন্য, apply
আপনাকে একক লাইনে এটি লেখার জন্য চেইন পদ্ধতি ব্যবহার করতে দেয় method অতএব আমরা কোনও ভেরিয়েবলের নামের সিদ্ধান্ত নেওয়ার প্রয়োজনটি সরিয়ে ফেলি, যা আসলে খুব বেশি আপনার অত্যন্ত মূল্যবান সংস্থান (আপনার মস্তিষ্ক !!) এর জন্য কম্পিউটেশনাল ব্যয়বহুল ।
এখানে পরিবর্তন আছে,
(
df.groupby(['state', 'office_id'])
.agg({'sales': 'sum'})
.groupby(level=0)
.apply(lambda x: 100 * x / float(x.sum()))
)
10.6 এমএস ± 81.5 µ গুলি প্রতি লুপ
(অর্থাত্ runs± রানের গড় dev৫ রান, প্রতিটি ১০০ টি লুপ)
সুতরাং কেউ একটি ছোট ডেটাসেটের 6ms সম্পর্কে যত্ন করে না। যাইহোক, এটি 3x গতি এবং উচ্চ কার্ডিনালিটি গ্রুপবাইয়ের সাথে একটি বৃহত্তর ডেটাসেটে এটি একটি বিশাল পার্থক্য আনতে চলেছে।
উপরের কোডটিতে যুক্ত করে আমরা 14412 রাষ্ট্র বিভাগ এবং 600 অফিস_আইডস সহ আকৃতির (12,000,000, 3) সহ একটি ডেটা ফ্রেম তৈরি করি,
import string
import numpy as np
import pandas as pd
np.random.seed(0)
groups = [
''.join(i) for i in zip(
np.random.choice(np.array([i for i in string.ascii_lowercase]), 30000),
np.random.choice(np.array([i for i in string.ascii_lowercase]), 30000),
np.random.choice(np.array([i for i in string.ascii_lowercase]), 30000),
)
]
df = pd.DataFrame({'state': groups * 400,
'office_id': list(range(1, 601)) * 20000,
'sales': [np.random.randint(100000, 999999)
for _ in range(12)] * 1000000
})
অ্যান্ডি ব্যবহার করে,
2 এস 10.4 এমএস প্রতি লুপ
(মানে ± স্ট্যান্ড। Dev রানের ডেভেল, প্রতিটি লুপ প্রতিটি)
এবং exp1orer
লুপ প্রতি 19 এস ± 77.1 এমএস
(7 of রানের গড় ± স্ট্যান্ডার্ড। প্রতিটি লুপ প্রতিটি)
সুতরাং এখন আমরা বড়, উচ্চ কার্ডিনালিটি ডেটাসেটগুলিতে এক্স 10 গতি বাড়িয়ে দেখছি।
আপনি যদি এই একটিকে ইউভি করেন তবে এই তিনটি উত্তরকে অবশ্যই ইউভি নিশ্চিত করুন!
df['sales'] / df.groupby('state')['sales'].transform('sum')
সবচেয়ে পরিষ্কার উত্তর বলে মনে হচ্ছে।