70

R の expand.grid() 関数に似た Python 関数はありますか? 前もって感謝します。

(編集) 以下は、この R 関数の説明と例です。

Create a Data Frame from All Combinations of Factors

Description:

     Create a data frame from all combinations of the supplied vectors
     or factors.  

> x <- 1:3
> y <- 1:3
> expand.grid(x,y)
  Var1 Var2
1    1    1
2    2    1
3    3    1
4    1    2
5    2    2
6    3    2
7    1    3
8    2    3
9    3    3

(EDIT2) 以下は rpy パッケージの例です。R を使用せずに同じ出力オブジェクトを取得したい:

>>> from rpy import *
>>> a = [1,2,3]
>>> b = [5,7,9]
>>> r.assign("a",a)
[1, 2, 3]
>>> r.assign("b",b)
[5, 7, 9]
>>> r("expand.grid(a,b)")
{'Var1': [1, 2, 3, 1, 2, 3, 1, 2, 3], 'Var2': [5, 5, 5, 7, 7, 7, 9, 9, 9]}

編集 02/09/2012: Python で本当に迷っています。彼の答えで与えられた Lev Levitsky のコードは私にとってはうまくいきません:

>>> a = [1,2,3]
>>> b = [5,7,9]
>>> expandgrid(a, b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in expandgrid
NameError: global name 'itertools' is not defined

ただし、itertools モジュールはインストールされているようです (入力from itertools import *してもエラー メッセージは返されません)。

4

11 に答える 11

45

リスト内包表記を使用するだけです:

>>> [(x, y) for x in range(5) for y in range(5)]

[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4)]

必要に応じて、numpy 配列に変換します。

>>> import numpy as np
>>> x = np.array([(x, y) for x in range(5) for y in range(5)])
>>> x.shape
(25, 2)

私は 10000 x 10000 までテストしましたが、Python のパフォーマンスは R の expand.grid のパフォーマンスに匹敵します。タプル (x, y) を使用すると、内包表記でリスト [x, y] を使用するよりも約 40% 高速です。

また...

np.meshgrid を使用すると約 3 倍高速になり、メモリの使用量がはるかに少なくなります。

%timeit np.array(np.meshgrid(range(10000), range(10000))).reshape(2, 100000000).T
1 loops, best of 3: 736 ms per loop

Rで:

> system.time(expand.grid(1:10000, 1:10000))
   user  system elapsed 
  1.991   0.416   2.424 

Python は 0 から始まる配列ですが、R には 1 から始まる配列があることに注意してください。

于 2015-05-07T20:04:28.820 に答える
27

productfromitertoolsがソリューションの鍵です。入力のデカルト積を生成します。

from itertools import product

def expand_grid(dictionary):
   return pd.DataFrame([row for row in product(*dictionary.values())], 
                       columns=dictionary.keys())

dictionary = {'color': ['red', 'green', 'blue'], 
              'vehicle': ['car', 'van', 'truck'], 
              'cylinders': [6, 8]}

>>> expand_grid(dictionary)
    color  cylinders vehicle
0     red          6     car
1     red          6     van
2     red          6   truck
3     red          8     car
4     red          8     van
5     red          8   truck
6   green          6     car
7   green          6     van
8   green          6   truck
9   green          8     car
10  green          8     van
11  green          8   truck
12   blue          6     car
13   blue          6     van
14   blue          6   truck
15   blue          8     car
16   blue          8     van
17   blue          8   truck
于 2015-09-13T12:49:31.943 に答える
19

必要なものと同様の出力を提供する例を次に示します。

import itertools
def expandgrid(*itrs):
   product = list(itertools.product(*itrs))
   return {'Var{}'.format(i+1):[x[i] for x in product] for i in range(len(itrs))}

>>> a = [1,2,3]
>>> b = [5,7,9]
>>> expandgrid(a, b)
{'Var1': [1, 1, 1, 2, 2, 2, 3, 3, 3], 'Var2': [5, 7, 9, 5, 7, 9, 5, 7, 9]}

itertools.product この違いは、反復ごとに右端の要素が進むという事実に関連しています。product重要な場合は、リストをスマートに並べ替えることで関数を微調整できます。

于 2012-08-26T15:32:30.977 に答える
19

pandasのドキュメントexpand_gridでは、次の関数が定義されています。

def expand_grid(data_dict):
    """Create a dataframe from every combination of given values."""
    rows = itertools.product(*data_dict.values())
    return pd.DataFrame.from_records(rows, columns=data_dict.keys())

このコードが機能するには、次の 2 つのインポートが必要です。

import itertools
import pandas as pd

出力は、pandas.DataFramePython で R に最も匹敵するオブジェクトである ですdata.frame

于 2016-09-17T20:43:53.767 に答える
18

私はこれについてしばらく疑問に思っていましたが、これまでに提案された解決策に満足していませんでした。この関数は numpy.meshgrid を使用してグリッドを作成し、グリッドを 1 次元配列にフラット化してまとめます。

def expand_grid(x, y):
    xG, yG = np.meshgrid(x, y) # create the actual grid
    xG = xG.flatten() # make the grid 1d
    yG = yG.flatten() # same
    return pd.DataFrame({'x':xG, 'y':yG}) # return a dataframe

例えば:

import numpy as np
import pandas as pd

p, q = np.linspace(1, 10, 10), np.linspace(1, 10, 10)

def expand_grid(x, y):
    xG, yG = np.meshgrid(x, y) # create the actual grid
    xG = xG.flatten() # make the grid 1d
    yG = yG.flatten() # same
    return pd.DataFrame({'x':xG, 'y':yG})

print expand_grid(p, q).head(n = 20)

これが古い投稿であることはわかっていますが、簡単なバージョンを共有したいと思いました!

于 2014-01-16T05:44:02.817 に答える
4

pandas.DataFrame を返す別のバージョンを次に示します。

import itertools as it
import pandas as pd

def expand_grid(*args, **kwargs):
    columns = []
    lst = []
    if args:
        columns += xrange(len(args))
        lst += args
    if kwargs:
        columns += kwargs.iterkeys()
        lst += kwargs.itervalues()
    return pd.DataFrame(list(it.product(*lst)), columns=columns)

print expand_grid([0,1], [1,2,3])
print expand_grid(a=[0,1], b=[1,2,3])
print expand_grid([0,1], b=[1,2,3])
于 2013-02-14T12:28:34.610 に答える