Python 从itertools产品创建数据帧
我有两份清单:Python 从itertools产品创建数据帧,python,pandas,numpy,dataframe,itertools,Python,Pandas,Numpy,Dataframe,Itertools,我有两份清单: a = [1,2,3] b = [4,5,6] 我想创建一个数据框,其中(a,b)的每个组合都会生成一个X数据框,然后我选择X的最大值,并使用a和b中的元素生成输出行/列 df=[] for i, j in itertools.product(a, b): X = do_something(i,j) ## this is a dataframe x_value = X.max() df.append(i,j,x_value) df=pd.DataF
a = [1,2,3]
b = [4,5,6]
我想创建一个数据框,其中(a,b)的每个组合都会生成一个X数据框,然后我选择X的最大值,并使用a和b中的元素生成输出行/列
df=[]
for i, j in itertools.product(a, b):
X = do_something(i,j) ## this is a dataframe
x_value = X.max()
df.append(i,j,x_value)
df=pd.DataFrame(df, columns=['a', 'b', 'x_value'])
1 2 3
4
5
6
输出数据框的列应为a,行应为b,值应为x\u值
df=[]
for i, j in itertools.product(a, b):
X = do_something(i,j) ## this is a dataframe
x_value = X.max()
df.append(i,j,x_value)
df=pd.DataFrame(df, columns=['a', 'b', 'x_value'])
1 2 3
4
5
6
IIUC,您想知道如何从
(i,j,x)
值列表转到一个数据帧,其中i
对应于列、j
索引和x
值:
例如,如果您有:
a = [1,2,3]
b = [4,5,6]
func = lambda i, j: i+j
result = [(i, j, func(i,j)) for i, j in itertools.product(a, b)]
print(result)
#[(1, 4, 5),
# (1, 5, 6),
# (1, 6, 7),
# (2, 4, 6),
# (2, 5, 7),
# (2, 6, 8),
# (3, 4, 7),
# (3, 5, 8),
# (3, 6, 9)]
将其转换为数据帧的一种方法是使用集合。defaultdict
:
from collections import defaultdict
d = defaultdict(list)
for i, j, x in result:
d[i].append(x)
df = pd.DataFrame(d, index=b)
print(df)
# 1 2 3
#4 5 6 7
#5 6 7 8
#6 7 8 9
IIUC
您可以避免使用
itertools.product
,同时通过使用numpy和广播实现相同的功能:
a = [1,2,3]
b = [4,5,6]
arr = np.array(a).reshape(-1, 1) + np.array(b).reshape(1, -1)
df = pd.DataFrame(arr, columns=a, index=b)
您的“索引”和值列表:
In [140]: alist = []
In [142]: for i,j in itertools.product(a,b):
...: v = i*2 + j*.5
...: alist.append([i,j,v])
...:
In [143]: alist
Out[143]:
[[1, 4, 4.0],
[1, 5, 4.5],
[1, 6, 5.0],
[2, 4, 6.0],
[2, 5, 6.5],
[2, 6, 7.0],
[3, 4, 8.0],
[3, 5, 8.5],
[3, 6, 9.0]]
一个3列数据帧,其中:
In [144]: df = pd.DataFrame(alist, columns=['a','b','value'])
In [145]: df
Out[145]:
a b value
0 1 4 4.0
1 1 5 4.5
2 1 6 5.0
3 2 4 6.0
4 2 5 6.5
5 2 6 7.0
6 3 4 8.0
7 3 5 8.5
8 3 6 9.0
使用相同数据生成“网格”数据帧的一种方法:
In [147]: pd.DataFrame(np.array(alist)[:,2].reshape(3,3), columns=a, index=b)
Out[147]:
1 2 3
4 4.0 4.5 5.0
5 6.0 6.5 7.0
6 8.0 8.5 9.0
错误映射行和列的Oops;让我们转置3x3阵列:
In [149]: pd.DataFrame(np.array(alist)[:,2].reshape(3,3).T, columns=a, index=b)
Out[149]:
1 2 3
4 4.0 6.0 8.0
5 4.5 6.5 8.5
6 5.0 7.0 9.0
我很了解numpy;我对熊猫的经验有限。我相信还有其他方法可以构建这样一个框架。我的猜测是,如果您的值函数足够复杂,那么迭代机制对总体运行时间的影响很小。简单地评估每个单元的功能将占用大部分时间
如果您的函数可以编写为接受数组,而不是标量,那么无需进行迭代即可轻松计算值。例如:
In [171]: I,J = np.meshgrid(b,a,indexing='ij')
In [172]: X = J*2 + I*.5
In [173]: X
Out[173]:
array([[4. , 6. , 8. ],
[4.5, 6.5, 8.5],
[5. , 7. , 9. ]])
In [174]: I
Out[174]:
array([[4, 4, 4],
[5, 5, 5],
[6, 6, 6]])
In [175]: J
Out[175]:
array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3]])
我在简化func(x),如果x比一个简单的加法更复杂怎么办?它必须是itertools,因为每个(I,j)生成一个数据帧(temp),我在tempEvery(I,j)中选择一个特定值创建一个数据帧x,这是我选的最大值value@user44840我已经根据您最新的更新修改了我的答案,最适合创建一个2d dfyes,这是正确的——更新后的itDoes
func
take scalarI
和j
?因此,它必须在创建数据帧之前或之后迭代应用?不,函数非常复杂,但每次迭代的最终结果(i,j)是一个生成了许多列的数据帧。然后,我从列中选择一个值有两个问题,1)为a
和b
的笛卡尔乘积生成x_值
,2)在数据帧中使用a
和b
列和行排列值。您的代码做得很好,但生成了一个不同的数据帧,一个包含3列和9行。但数据都在那里。