我有兩列下面的資料幀c1和c2,我想添加一個新列c3基于以下邏輯,我的作品,但速度很慢的東西,任何人都可以提出一個方法向量化呢?
- 必須基于
c1and進行分組c2,然后對于每個組,新列c3必須從values鍵為值的位置依次填充c1,每個“子組”將具有后續值 IOWvalues[value_of_c1][idx],其中idx是“子組”,示例如下 - 第一個組
(1, 'a'),這里c1是1,“子組”"a"索引是0(第一個子組 1)所以c3對于這個組中的所有行values[1][0] (1, 'b')這里的第二個組c1仍然是,1但是“子組”是"b"索引1(第二個子組為 1)所以對于這個組中的所有行c3都是values[1][1]- 第三組
(2, 'y')在這里c1是現在2,“子組”是"a"與索引0(第一子組的2),所以對所有的行在這一組c3是values[2][0] - 等等
values將有必要的元素來滿足這個邏輯。
代碼
import pandas as pd
df = pd.DataFrame(
{
"c1": [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2],
"c2": ["a", "a", "a", "b", "b", "b", "y", "y", "y", "z", "z", "z"],
}
)
new_df = pd.DataFrame()
values = {1: ["a1", "a2"], 2: ["b1", "b2"]}
for i, j in df.groupby("c1"):
for idx, (k, l) in enumerate(j.groupby("c2")):
l["c3"] = values[i][idx]
new_df = new_df.append(l)
輸出(有效,但我的代碼很慢)
c1 c2 c3
0 1 a a1
1 1 a a1
2 1 a a1
3 1 b a2
4 1 b a2
5 1 b a2
6 2 y b1
7 2 y b1
8 2 y b1
9 2 z b2
10 2 z b2
11 2 z b2
uj5u.com熱心網友回復:
如果你不介意使用另一個庫,你基本上需要在你的組中標記編碼:
from sklearn.preprocessing import LabelEncoder
def le(x):
return pd.DataFrame(LabelEncoder().fit_transform(x),index=x.index)
df['idx'] = df.groupby('c1')['c2'].apply(le)
df['c3'] = df.apply(lambda x:values[x['c1']][x['idx']],axis=1)
c1 c2 idx c3
0 1 a 0 a1
1 1 a 0 a1
2 1 a 0 a1
3 1 b 1 a2
4 1 b 1 a2
5 1 b 1 a2
6 2 y 0 b1
7 2 y 0 b1
8 2 y 0 b1
9 2 z 1 b2
10 2 z 1 b2
11 2 z 1 b2
否則就是使用pd.Categorical與上面相同的概念,只是您在每個組內將列轉換為類別,然后取出代碼:
def le(x):
return pd.DataFrame(pd.Categorical(x).codes,index=x.index)
uj5u.com熱心網友回復:
In [203]: a = pd.DataFrame([[k, value, idx] for k,v in values.items() for idx,value in enumerate(v)], columns=['c1', 'c3', 'gr'])
...: b = df.assign(gr=df.groupby(['c1']).transform(lambda x: (x.ne(x.shift()).cumsum())- 1))
...: print(b)
...: b.merge(a).drop(columns='gr')
...:
# b
c1 c2 gr
0 1 a 0
1 1 a 0
2 1 a 0
3 1 b 1
4 1 b 1
5 1 b 1
6 2 y 0
7 2 y 0
8 2 y 0
9 2 z 1
10 2 z 1
11 2 z 1
Out[203]:
c1 c2 c3
0 1 a a1
1 1 a a1
2 1 a a1
3 1 b a2
4 1 b a2
5 1 b a2
6 2 y b1
7 2 y b1
8 2 y b1
9 2 z b2
10 2 z b2
11 2 z b2
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/369035.html
