将 x 个相同大小的 2D numpy 数组转换为 2+x 列数据框
Convert x same size 2D numpy arrays to a 2+x column data frame
我有两个大小为 (m x n) 的 ndarray,以及两个长度分别为 m 和 n 的列表。我想将这两个矩阵转换为具有四列的数据框。前两列对应于 m 和 n 维度,并包含列表中的值。接下来的两列应包含来自两个矩阵的值。总的来说,生成的数据框应该有 m 乘以 n 行。
示例:
如果这些是两个矩阵和两个列表,
a1 = np.array([[1, 2], [3, 4],[5,6]])
a2 = np.array([[10, 20], [30, 40],[50,60]])
l1 = [5,7,99]
l2 = [2,3]
那么生成的数据框应该如下所示:
"l1" "l2" "a1" "a2"
5 2 1 10
7 2 3 30
99 2 5 50
5 3 2 20
7 3 4 40
99 3 6 60
行的顺序无关紧要。
虽然在这种特定情况下我只有两个矩阵,但我很好奇可以轻松适用于任意数量的相同大小矩阵的解决方案。
使用np.vstack
for join arrays created by numpy.tile
, numpy.repeat
and numpy.ravel
并传递给DataFrame
构造函数:
a = np.vstack((np.tile(l1, len(l2)),
np.repeat(l2, len(l1)),
np.ravel(a1, 'F'),
np.ravel(a2, 'F'))).T
print (a)
[[ 5 2 1 10]
[ 7 2 3 30]
[99 2 5 50]
[ 5 3 2 20]
[ 7 3 4 40]
[99 3 6 60]]
df = pd.DataFrame(a, columns=['l1','l2','a1','a2'])
print (df)
l1 l2 a1 a2
0 5 2 1 10
1 7 2 3 30
2 99 2 5 50
3 5 3 2 20
4 7 3 4 40
5 99 3 6 60
对于多个数组:
arrays = [a1, a2]
arr = [np.ravel(a, 'F') for a in arrays]
a = np.vstack((np.tile(l1, len(l2)),
np.repeat(l2, len(l1)),
arr)).T
print (a)
[[ 5 2 1 10]
[ 7 2 3 30]
[99 2 5 50]
[ 5 3 2 20]
[ 7 3 4 40]
[99 3 6 60]]
df = pd.DataFrame(a, columns=['l1','l2'] + [f'a{x+1}' for x in range(len(arrays))])
print (df)
l1 l2 a1 a2
0 5 2 1 10
1 7 2 3 30
2 99 2 5 50
3 5 3 2 20
4 7 3 4 40
5 99 3 6 60
Pandas 只有 concat
and DataFrame.unstack
的解决方案:
df = (pd.concat([pd.DataFrame(a1, columns=l2, index=l1).unstack(),
pd.DataFrame(a2, columns=l2, index=l1).unstack()],
axis=1, keys=['a1','a2'])
.rename_axis(['l2','l1']).swaplevel(1,0).reset_index())
print (df)
l1 l2 a1 a2
0 5 2 1 10
1 7 2 3 30
2 99 2 5 50
3 5 3 2 20
4 7 3 4 40
5 99 3 6 60
对于多个数组:
arrays = [a1, a2]
df = (pd.concat([pd.DataFrame(a, columns=l2, index=l1).unstack() for a in arrays],
axis=1)
.rename_axis(['l2','l1'])
.swaplevel(1,0)
.rename(columns=lambda x: f'a{x+1}')
.reset_index())
print (df)
l1 l2 a1 a2
0 5 2 1 10
1 7 2 3 30
2 99 2 5 50
3 5 3 2 20
4 7 3 4 40
5 99 3 6 60
扩展 jezrael 对多个数组的出色回答:
arrays = ... # e.g [a1, a2]
a = np.vstack([np.tile(l1, len(l2),
np.repeat(l2, len(l1))] +
[np.ravel(a, 'F') for a in arrays]).T
这应该可以解决您的问题:
import pandas as pd
import numpy as np
df=pd.DataFrame()
a1 = np.array([[1, 2], [3, 4],[5,6]])
a2 = np.array([[10, 20], [30, 40],[50,60]])
l1 = [5,7,99]
l2 = [2,3]
m,n=len(l1),len(l2)
temp_l1=[]
for i in l1:
temp_l1.extend([i]*n)
df["l1"]=temp_l1
df["l2"]=l2*m
df["a1"]=a1.flatten()
df["a2"]=a2.flatten()
print(df)
输出:
l1 l2 a1 a2
0 5 2 1 10
1 5 3 2 20
2 7 2 3 30
3 7 3 4 40
4 99 2 5 50
5 99 3 6 60
我有两个大小为 (m x n) 的 ndarray,以及两个长度分别为 m 和 n 的列表。我想将这两个矩阵转换为具有四列的数据框。前两列对应于 m 和 n 维度,并包含列表中的值。接下来的两列应包含来自两个矩阵的值。总的来说,生成的数据框应该有 m 乘以 n 行。
示例: 如果这些是两个矩阵和两个列表,
a1 = np.array([[1, 2], [3, 4],[5,6]])
a2 = np.array([[10, 20], [30, 40],[50,60]])
l1 = [5,7,99]
l2 = [2,3]
那么生成的数据框应该如下所示:
"l1" "l2" "a1" "a2"
5 2 1 10
7 2 3 30
99 2 5 50
5 3 2 20
7 3 4 40
99 3 6 60
行的顺序无关紧要。
虽然在这种特定情况下我只有两个矩阵,但我很好奇可以轻松适用于任意数量的相同大小矩阵的解决方案。
使用np.vstack
for join arrays created by numpy.tile
, numpy.repeat
and numpy.ravel
并传递给DataFrame
构造函数:
a = np.vstack((np.tile(l1, len(l2)),
np.repeat(l2, len(l1)),
np.ravel(a1, 'F'),
np.ravel(a2, 'F'))).T
print (a)
[[ 5 2 1 10]
[ 7 2 3 30]
[99 2 5 50]
[ 5 3 2 20]
[ 7 3 4 40]
[99 3 6 60]]
df = pd.DataFrame(a, columns=['l1','l2','a1','a2'])
print (df)
l1 l2 a1 a2
0 5 2 1 10
1 7 2 3 30
2 99 2 5 50
3 5 3 2 20
4 7 3 4 40
5 99 3 6 60
对于多个数组:
arrays = [a1, a2]
arr = [np.ravel(a, 'F') for a in arrays]
a = np.vstack((np.tile(l1, len(l2)),
np.repeat(l2, len(l1)),
arr)).T
print (a)
[[ 5 2 1 10]
[ 7 2 3 30]
[99 2 5 50]
[ 5 3 2 20]
[ 7 3 4 40]
[99 3 6 60]]
df = pd.DataFrame(a, columns=['l1','l2'] + [f'a{x+1}' for x in range(len(arrays))])
print (df)
l1 l2 a1 a2
0 5 2 1 10
1 7 2 3 30
2 99 2 5 50
3 5 3 2 20
4 7 3 4 40
5 99 3 6 60
Pandas 只有 concat
and DataFrame.unstack
的解决方案:
df = (pd.concat([pd.DataFrame(a1, columns=l2, index=l1).unstack(),
pd.DataFrame(a2, columns=l2, index=l1).unstack()],
axis=1, keys=['a1','a2'])
.rename_axis(['l2','l1']).swaplevel(1,0).reset_index())
print (df)
l1 l2 a1 a2
0 5 2 1 10
1 7 2 3 30
2 99 2 5 50
3 5 3 2 20
4 7 3 4 40
5 99 3 6 60
对于多个数组:
arrays = [a1, a2]
df = (pd.concat([pd.DataFrame(a, columns=l2, index=l1).unstack() for a in arrays],
axis=1)
.rename_axis(['l2','l1'])
.swaplevel(1,0)
.rename(columns=lambda x: f'a{x+1}')
.reset_index())
print (df)
l1 l2 a1 a2
0 5 2 1 10
1 7 2 3 30
2 99 2 5 50
3 5 3 2 20
4 7 3 4 40
5 99 3 6 60
扩展 jezrael 对多个数组的出色回答:
arrays = ... # e.g [a1, a2]
a = np.vstack([np.tile(l1, len(l2),
np.repeat(l2, len(l1))] +
[np.ravel(a, 'F') for a in arrays]).T
这应该可以解决您的问题:
import pandas as pd
import numpy as np
df=pd.DataFrame()
a1 = np.array([[1, 2], [3, 4],[5,6]])
a2 = np.array([[10, 20], [30, 40],[50,60]])
l1 = [5,7,99]
l2 = [2,3]
m,n=len(l1),len(l2)
temp_l1=[]
for i in l1:
temp_l1.extend([i]*n)
df["l1"]=temp_l1
df["l2"]=l2*m
df["a1"]=a1.flatten()
df["a2"]=a2.flatten()
print(df)
输出:
l1 l2 a1 a2
0 5 2 1 10
1 5 3 2 20
2 7 2 3 30
3 7 3 4 40
4 99 2 5 50
5 99 3 6 60