将 table 旋转到 Pandas 中的 "tidy" 数据框
Pivot table to "tidy" data frame in Pandas
我有一个数字数组(我认为格式使它成为一个枢轴 table),我想将其转换为 "tidy" 数据框。例如,我从左侧的变量 1 开始,顶部是变量 2,中间是感兴趣的值,如下所示:
X Y
A 1 2
B 3 4
我想把它变成这样一个整洁的数据框:
V1 V2 value
A X 1
A Y 2
B X 3
B Y 4
行列顺序对我来说无关紧要,所以下面完全可以接受table:
value V1 V2
2 A Y
4 B Y
3 B X
1 A X
我第一次尝试这个能够得到正确的最终答案,我遍历了行和列。这太慢了,我怀疑 Pandas 中的某些机器会使它运行得更快。
似乎 melt
接近我所寻求的魔法,但它并没有让我一路走到那里。第一个数组变成了这个:
V2 value
0 X 1
1 X 2
2 Y 3
3 Y 4
它摆脱了我的 V1 变量!
melt
没有什么特别之处,所以我很乐意阅读使用其他方法的答案,特别是如果 melt
并不比我的嵌套循环快多少,而另一个解决方案是。尽管如此,我怎样才能从那个数组转到我想要的那种整洁的数据框作为输出?
示例数据框:
df = pd.DataFrame({"X":[1,3], "Y":[2,4]},index=["A","B"])
使用DataFrame.reset_index
with DataFrame.rename_axis
and then DataFrame.melt
. If you want order columns we could use DataFrame.reindex
.
new_df = (df.rename_axis(index = 'V1')
.reset_index()
.melt('V1',var_name='V2')
.reindex(columns = ['value','V1','V2']))
print(new_df)
另一种方法DataFrame.stack
:
new_df = (df.stack()
.rename_axis(index = ['V1','V2'])
.rename('value')
.reset_index()
.reindex(columns = ['value','V1','V2']))
print(new_df)
value V1 V2
0 1 A X
1 3 B X
2 2 A Y
3 4 B Y
为了命名还有另一种选择,比如在评论中评论 @Scott Boston
Melt 是一个很好的方法,但它似乎不能很好地通过索引识别结果。您可以先重置索引以将其移动到它自己的列,然后将该列用作 id col.
test = pd.DataFrame([[1,2],[3,4]], columns=['X', 'Y'], index=['A', 'B'])
X Y
A 1 2
B 3 4
test = test.reset_index()
index X Y
0 A 1 2
1 B 3 4
test.melt('index',['X', 'Y'], 'prev cols')
index prev cols value
0 A X 1
1 B X 3
2 A Y 2
3 B Y 4
我有一个数字数组(我认为格式使它成为一个枢轴 table),我想将其转换为 "tidy" 数据框。例如,我从左侧的变量 1 开始,顶部是变量 2,中间是感兴趣的值,如下所示:
X Y
A 1 2
B 3 4
我想把它变成这样一个整洁的数据框:
V1 V2 value
A X 1
A Y 2
B X 3
B Y 4
行列顺序对我来说无关紧要,所以下面完全可以接受table:
value V1 V2
2 A Y
4 B Y
3 B X
1 A X
我第一次尝试这个能够得到正确的最终答案,我遍历了行和列。这太慢了,我怀疑 Pandas 中的某些机器会使它运行得更快。
似乎 melt
接近我所寻求的魔法,但它并没有让我一路走到那里。第一个数组变成了这个:
V2 value
0 X 1
1 X 2
2 Y 3
3 Y 4
它摆脱了我的 V1 变量!
melt
没有什么特别之处,所以我很乐意阅读使用其他方法的答案,特别是如果 melt
并不比我的嵌套循环快多少,而另一个解决方案是。尽管如此,我怎样才能从那个数组转到我想要的那种整洁的数据框作为输出?
示例数据框:
df = pd.DataFrame({"X":[1,3], "Y":[2,4]},index=["A","B"])
使用DataFrame.reset_index
with DataFrame.rename_axis
and then DataFrame.melt
. If you want order columns we could use DataFrame.reindex
.
new_df = (df.rename_axis(index = 'V1')
.reset_index()
.melt('V1',var_name='V2')
.reindex(columns = ['value','V1','V2']))
print(new_df)
另一种方法DataFrame.stack
:
new_df = (df.stack()
.rename_axis(index = ['V1','V2'])
.rename('value')
.reset_index()
.reindex(columns = ['value','V1','V2']))
print(new_df)
value V1 V2
0 1 A X
1 3 B X
2 2 A Y
3 4 B Y
为了命名还有另一种选择,比如在评论中评论 @Scott Boston
Melt 是一个很好的方法,但它似乎不能很好地通过索引识别结果。您可以先重置索引以将其移动到它自己的列,然后将该列用作 id col.
test = pd.DataFrame([[1,2],[3,4]], columns=['X', 'Y'], index=['A', 'B'])
X Y
A 1 2
B 3 4
test = test.reset_index()
index X Y
0 A 1 2
1 B 3 4
test.melt('index',['X', 'Y'], 'prev cols')
index prev cols value
0 A X 1
1 B X 3
2 A Y 2
3 B Y 4