[英]Transform DataFrame in Pandas
我正在努力解決以下問題。
我的DF是:
df = pd.DataFrame(
[
['7890-1', '12345N', 'John', 'Intermediate'],
['7890-4', '30909N', 'Greg', 'Intermediate'],
['3300-1', '88117N', 'Mark', 'Advanced'],
['2502-2', '90288N', 'Olivia', 'Elementary'],
['7890-2', '22345N', 'Joe', 'Intermediate'],
['7890-3', '72245N', 'Ana', 'Elementary']
],
columns=['Id', 'Code', 'Person', 'Level'])
print(df)
我想得到這樣的結果:
ID | 代碼 1 | 人 1 | 1級 | 代碼 2 | 人 2 | 2級 | 代碼 3 | 人 3 | 3級 | 代碼 4 | 人 4 | 4級 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 7890 | 12345N | 約翰 | 中間的 | 22345N | 喬 | 中間的 | 72245N | 安娜 | 初級 | 30909N | 格雷格 | 中間的 |
1 | 3300 | 88117N | 標記 | 先進的 | 鈉 | 鈉 | 鈉 | 鈉 | 鈉 | 鈉 | 鈉 | 鈉 | 鈉 |
2 | 2502 | 鈉 | 鈉 | 鈉 | 90288N | 奧利維亞 | 初級 | 鈉 | 鈉 | 鈉 | 鈉 | 鈉 | 鈉 |
嘗試:
df[["Id", "Id2"]] = df["Id"].str.split("-", expand=True)
x = df.set_index(["Id", "Id2"]).unstack(level=1)
x.columns = [f"{a} {b}" for a, b in x.columns]
print(
x[sorted(x.columns, key=lambda k: int(k.split()[-1]))]
.reset_index()
.to_markdown()
)
印刷:
ID | 代碼 1 | 人 1 | 1級 | 代碼 2 | 人 2 | 2級 | 代碼 3 | 人 3 | 3級 | 代碼 4 | 人 4 | 4級 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2502 | 楠 | 楠 | 楠 | 90288N | 奧利維亞 | 初級 | 楠 | 楠 | 楠 | 楠 | 楠 | 楠 |
1 | 3300 | 88117N | 標記 | 先進的 | 楠 | 楠 | 楠 | 楠 | 楠 | 楠 | 楠 | 楠 | 楠 |
2 | 7890 | 12345N | 約翰 | 中間的 | 22345N | 喬 | 中間的 | 72245N | 安娜 | 初級 | 30909N | 格雷格 | 中間的 |
我將從與@Andrej Kesely 相同的方法開始,但在取消堆疊后按索引排序並使用' '.join
map
列名。
df[["Id", "No"]] = df["Id"].str.split("-", expand=True)
df_wide = df.set_index(["Id", "No"]).unstack(level=1).sort_index(axis=1,level=1)
df_wide.columns = df_wide.columns.map(' '.join)
輸出
Code 1 Level 1 Person 1 Code 2 Level 2 Person 2 Code 3 \
Id
2502 NaN NaN NaN 90288N Elementary Olivia NaN
3300 88117N Advanced Mark NaN NaN NaN NaN
7890 12345N Intermediate John 22345N Intermediate Joe 72245N
Level 3 Person 3 Code 4 Level 4 Person 4
Id
2502 NaN NaN NaN NaN NaN
3300 NaN NaN NaN NaN NaN
7890 Elementary Ana 30909N Intermediate Greg
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.