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的最大值,并使用ab中的元素生成输出行/列

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 scalar
I
j
?因此,它必须在创建数据帧之前或之后迭代应用?不,函数非常复杂,但每次迭代的最终结果(i,j)是一个生成了许多列的数据帧。然后,我从列中选择一个值有两个问题,1)为
a
b
的笛卡尔乘积生成
x_值
,2)在数据帧中使用
a
b
列和行排列值。您的代码做得很好,但生成了一个不同的数据帧,一个包含3列和9行。但数据都在那里。