1 回答

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超7個(gè)贊
.values根據(jù)您的命名約定,確保列已排序并用于對(duì)齊操作。可以.where用來填滿一切。如果您想在缺少列的情況下更安全(即您有 Pac.31 但沒有 Pdc.31),則映射操作的列名,以保證對(duì)齊。
import pandas as pd
#df = df.sort_index(axis=1)
pac = df.filter(like='Pac')
pdc = df.filter(like='Pdc')
df_res = pd.concat([pac.where(pac.notnull(), pdc.multiply(pac.mean().div(pdc.mean().values).values).values),
pdc.where(pdc.notnull(), pac.multiply(pdc.mean().div(pac.mean().values).values).values)
], axis=1)
輸出df_res:
Pac Pac.1 Pac.2 Pdc Pdc.1 Pdc.2
0 1.000000 6.0 3.000000 1.285714 4.952381 2.0
1 1.555556 1.0 2.000000 2.000000 2.000000 1.0
2 7.000000 6.0 3.714286 7.000000 4.952381 3.0
3 6.000000 7.0 5.000000 5.000000 5.000000 7.0
4 5.000000 2.0 3.714286 6.000000 1.650794 3.0
5 2.000000 7.0 4.000000 7.000000 5.000000 1.0
6 3.000000 4.0 3.000000 4.000000 1.000000 1.0
7 1.000000 5.0 3.000000 1.285714 7.000000 3.0
8 5.000000 5.0 6.000000 4.000000 5.000000 6.0
9 5.000000 2.0 3.714286 6.428571 1.000000 3.0
樣本數(shù)據(jù)
import numpy as np
df = pd.DataFrame(np.random.choice([1,2,3,4,5,6,7, np.NaN], (10,6)),
columns = ['Pdc', 'Pdc.1', 'Pdc.2', 'Pac', 'Pac.1', 'Pac.2'])
Pdc Pdc.1 Pdc.2 Pac Pac.1 Pac.2
0 NaN NaN 2.0 1.0 6.0 3.0
1 2.0 2.0 1.0 NaN 1.0 2.0
2 7.0 NaN 3.0 7.0 6.0 NaN
3 5.0 5.0 7.0 6.0 7.0 5.0
4 6.0 NaN 3.0 5.0 2.0 NaN
5 7.0 5.0 1.0 2.0 7.0 4.0
6 4.0 1.0 1.0 3.0 4.0 3.0
7 NaN 7.0 3.0 1.0 5.0 3.0
8 4.0 5.0 6.0 5.0 5.0 6.0
9 NaN 1.0 3.0 5.0 2.0 NaN
解釋:
第一步是對(duì)列進(jìn)行排序,然后過濾查找以字符串'Pac'或開頭的列'Pdc'。由于我們對(duì)索引進(jìn)行了排序,這保證了排序是一致的(只要組中的后綴集相同)
df = df.sort_index(axis=1)
pac = df.filter(like='Pac')
pdc = df.filter(like='Pdc')
print(pac.head(3))
# Pac Pac.1 Pac.2
#0 1.0 6.0 3.0
#1 NaN 1.0 2.0
#2 7.0 6.0 NaN
print(pdc.head(3))
# Pdc Pdc.1 Pdc.2
#0 NaN NaN 2.0
#1 2.0 2.0 1.0
#2 7.0 NaN 3.0
現(xiàn)在我們可以做數(shù)學(xué)了。忽略.fillna邏輯,只考慮計(jì)算我們將為所有內(nèi)容填充的內(nèi)容。DataFrame操作對(duì)準(zhǔn)被指數(shù)(兩行和列)。您可以看到pac并pdc共享行索引,但列索引(列名稱)不同,這會(huì)導(dǎo)致問題:
pac.mean()
#Pac 3.888889
#Pac.1 4.500000
#Pac.2 3.714286
#dtype: float64
pdc.mean()
#Pdc 5.000000
#Pdc.1 3.714286
#Pdc.2 3.000000
#dtype: float64
pac.mean().div(pdc.mean())
#Pac NaN
#Pac.1 NaN
#Pac.2 NaN
#Pdc NaN
#Pdc.1 NaN
#Pdc.2 NaN
但是,因?yàn)槲覀冎斑M(jìn)行了排序,我們可以看到它們values是對(duì)齊的,所以我們安全地劃分每列意味著訪問值數(shù)組。這給出了每Pac列的平均值除以相應(yīng)Pdc列的平均值。
pac.mean().div(pdc.mean().values)
#Pac 0.777778
#Pac.1 1.211538
#Pac.2 1.238095
#dtype: float64
乘法有同樣的對(duì)齊問題,所以再次訪問這些值,現(xiàn)在這給了我們一個(gè)DataFrame與子集相同的形狀,如果值為空,我們應(yīng)該填充:
pdc.multiply(pac.mean().div(pdc.mean().values).values)
# Pdc Pdc.1 Pdc.2
#0 NaN NaN 2.476190
#1 1.555556 2.423077 1.238095
#...
最后,fillna邏輯完成了,where因?yàn)槲覀冇袃蓚€(gè)DataFrames:
pac.where(pac.notnull(), pdc.multiply(pac.mean().div(pdc.mean().values).values).values)
可以理解為“在 pac 中使用不為空的值,否則使用計(jì)算中的值”,這正是我們想要的。我們?cè)俅涡枰L問.values'other'(第二個(gè)參數(shù))的 ,where因?yàn)榱忻俅尾煌?,但值是?duì)齊的。
分別為每個(gè)組執(zhí)行此操作,然后將它們重新加入。
添加回答
舉報(bào)