Rumah >pembangunan bahagian belakang >Tutorial Python >Kira jumlah setiap baris indeks luaran dalam bingkai data panda berbilang indeks

Kira jumlah setiap baris indeks luaran dalam bingkai data panda berbilang indeks

WBOY
WBOYke hadapan
2024-02-05 22:00:131148semak imbas

计算多索引 pandas 数据帧外部索引每行的总和

Kandungan soalan

Saya mempunyai bingkai data: gabungan termurah selleritempriceshipping免费送货最低count availablecount required。我的目标是根据稍后计算的 total 找到 selleritem (kod pengiraan ditunjukkan di bawah). Data sampel adalah seperti berikut:

import pandas as pd

item1 = ['item 1', 'item 2', 'item 1', 'item 1', 'item 2']
seller1 = ['seller 1', 'seller 2', 'seller 3', 'seller 4', 'seller 1']
price1 = [1.85, 1.94, 2.00, 2.00, 2.02]
shipping1 = [0.99, 0.99, 0.99, 2.99, 0.99]
freeship1 = [5, 5, 5, 50, 5]
countavailable1 = [1, 2, 2, 5, 2]
countneeded1 = [2, 1, 2, 2, 1]

df1 = pd.dataframe({'seller':seller1,
                    'item':item1,
                    'price':price1,
                    'shipping':shipping1,
                    'free shipping minimum':freeship1,
                    'count available':countavailable1,
                    'count needed':countneeded1})

# create columns that states if seller has all counts needed.
# this will be used to sort by to prioritize the smallest number of orders possible
for index, row in df1.iterrows():
    if row['count available'] >= row['count needed']:
        df1.at[index, 'fulfills count needed'] = 'yes'
    else:
        df1.at[index, 'fulfills count needed'] = 'no'

# dont want to calc price based on [count available], so need to check if seller has count i need and calc cost based on [count needed].
# if doesn't have [count needed], then calc cost on [count available].
for index, row in df1.iterrows():
    if row['count available'] >= row['count needed']:
        df1.at[index, 'price x count'] = row['count needed'] * row['price']
    else:
        df1.at[index, 'price x count'] = row['count available'] * row['price']

Walau bagaimanapun, sama ada seller都可以出售多个item。我想尽量减少支付的运费,所以我想通过 selleritems 分组在一起。因此,我根据我在另一个线程中看到的方式使用 .first() kaedah mengumpulkannya supaya setiap lajur disimpan dalam bingkai data terkumpul baharu.

# don't calc [total] until sellers have been grouped
# use first() method to return all columns and perform no other aggregations
grouped1 = df1.sort_values('price').groupby(['seller', 'item']).first()

Ketika ini saya mahu lulusseller计算total。所以我有以下代码,但它为每个 item 计算 total,而不是 seller,这意味着 shipping 根据每个组中的商品数量被多次添加,或者当 price x count 结束时不应用免费送货最低免运费.

# calc [Total]
for index, row in grouped1.iterrows():
    if (row['Free Shipping Minimum'] == 50) & (row['Price x Count'] > 50):
        grouped1.at[index, 'Total'] = row['Price x Count'] + 0
    elif (row['Free Shipping Minimum'] == 5) & (row['Price x Count'] > 5):
        grouped1.at[index, 'Total'] = row['Price x Count'] + 0
    else:
        grouped1.at[index, 'Total'] = row['Price x Count'] + row['Shipping']

Sebenarnya saya mungkin perlu mengira total 时对每个 seller 求和 price x count , tetapi itu pada asasnya masalah yang sama kerana saya tidak tahu cara mengira setiap baris indeks luar. Apakah kaedah yang boleh saya gunakan untuk melakukan ini?

Selain itu, jika sesiapa mempunyai sebarang cadangan tentang cara untuk mencapai separuh kedua matlamat saya, sila berasa bebas untuk bertanya. Saya cuma nak pulangkan setiap barang yang saya perlukan. Sebagai contoh, saya memerlukan 2 "Projek 1" dan 2 "Projek 2". Jika "Penjual 1" mempunyai 2 "Item 1" dan 1 "Item 2", dan "Penjual 2" mempunyai 1 "Item 1" dan 1 "Item 2", maka saya mahu semua Item "Penjual 1" (dengan andaian ia adalah paling murah), tetapi hanya terdapat 1 "Item1" untuk "Penjual2". Ini nampaknya menjejaskan pengiraan lajur total, tetapi saya tidak pasti cara untuk melaksanakannya. total 列的计算,但我不确定如何实现它。


正确答案


我最终决定首先对 seller 进行分组,并对 price x count 进行求和以找到 subtotals,将其转换为数据帧,然后将 df1 与新的 subtotal 数据帧合并以创建 groupedphpcnend cphpcn 数据框。然后我使用 <code>np.where 建议创建了 totals 列(这比我的 for 循环优雅得多,并且可以轻松处理 nan 值)。最后按sellertotalitem

Jawapan betul

🎜🎜Saya akhirnya memutuskan untuk mengumpulkan penjual dahulu dan menjumlahkan harga x kiraan untuk Cari subtotals, tukarkannya kepada dataframes, kemudian gabungkan df1 dengan subtotal dataframe untuk mencipta groupedphpcnend cphpcn data box. Saya kemudian mencipta lajur <code>totals menggunakan cadangan np.where (ini jauh lebih elegan daripada gelung for saya dan mengendalikan nilai nan dengan mudah). Akhir sekali, kumpulkan mengikut penjual, total, item untuk mengembalikan hasil yang saya inginkan. Kod akhir adalah seperti berikut: 🎜
import pandas as pd
import numpy as np

item1 = ['item 1', 'item 2', 'item 1', 'item 1', 'item 2']
seller1 = ['Seller 1', 'Seller 2', 'Seller 3', 'Seller 4', 'Seller 1']
price1 = [1.85, 1.94, 2.69, 2.00, 2.02]
shipping1 = [0.99, 0.99, 0.99, 2.99, 0.99]
freeship1 = [5, 5, 5, 50, 5]
countavailable1 = [1, 2, 2, 5, 2]
countneeded1 = [2, 1, 2, 2, 1]

df1 = pd.DataFrame({'Seller':seller1,
                    'Item':item1,
                    'Price':price1,
                    'Shipping':shipping1,
                    'Free Shipping Minimum':freeship1,
                    'Count Available':countavailable1,
                    'Count Needed':countneeded1})

# create columns that states if seller has all counts needed.
# this will be used to sort by to prioritize the smallest number of orders possible
for index, row in df1.iterrows():
    if row['Count Available'] >= row['Count Needed']:
        df1.at[index, 'Fulfills Count Needed'] = 'Yes'
    else:
        df1.at[index, 'Fulfills Count Needed'] = 'No'

# dont want to calc price based on [count available], so need to check if seller has count I need and calc cost based on [count needed].
# if doesn't have [count needed], then calc cost on [count available].
for index, row in df1.iterrows():
    if row['Count Available'] >= row['Count Needed']:
        df1.at[index, 'Price x Count'] = row['Count Needed'] * row['Price']
    else:
        df1.at[index, 'Price x Count'] = row['Count Available'] * row['Price']

# subtotals by seller, then assign calcs to column called [Subtotal] and merge into dataframe
subtotals = df1.groupby(['Seller'])['Price x Count'].sum().reset_index()

subtotals.rename({'Price x Count':'Subtotal'}, axis=1, inplace=True)

grouped = df1.merge(subtotals[['Subtotal', 'Seller']], on='Seller')


# calc [Total]
grouped['Total'] = np.where(grouped['Subtotal'] > grouped['Free Shipping Minimum'],
                             grouped['Subtotal'], grouped['Subtotal'] + grouped['Shipping'])

grouped.groupby(['Seller', 'Total', 'Item']).first()

Atas ialah kandungan terperinci Kira jumlah setiap baris indeks luaran dalam bingkai data panda berbilang indeks. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam