簡體   English   中英

從兩個不相關的系列創建DataFrame的最有效方法是什么?

[英]What is the most efficient way to create a DataFrame from two unrelated series?

我正在考慮創建一個Dataframe,它是兩個不相關的系列的組合。

如果我們采用兩個數據幀:

A = ['a','b','c']
B = [1,2,3,4]

dfA = pd.DataFrame(A)
dfB = pd.DataFrame(B)

我正在尋找這個輸出:

    A  B
0   a  1
1   a  2
2   a  3
3   a  4
4   b  1
5   b  2
6   b  3
7   b  4
8   c  1
9   c  2
10  c  3
11  c  4

一種方法是在列表direclty上創建循環並創建DataFrame,但必須有更好的方法。 我敢肯定我錯過了熊貓文檔中的一些東西。

result = []
for i in A:
    for j in B:
        result.append([i,j])

result_DF = pd.DataFrame(result,columns=['A','B'])

最終我正在考慮結合幾個月和UUID,我有一些工作,但它需要很長的時間來計算和過多依賴索引。 通用解決方案顯然會更好:

from datetime import datetime

start = datetime(year=2016,month=1,day=1)
end = datetime(year=2016,month=4,day=1)
months = pd.DatetimeIndex(start=start,end=end,freq="MS")
benefit = pd.DataFrame(index=months)

A = [UUID('d48259a6-80b5-43ca-906c-8405ab40f9a8'),
   UUID('873a65d7-582c-470e-88b6-0d02df078c04'),
   UUID('624c32a6-9998-49f4-92b6-70e712355073'),
   UUID('7207ab0c-3c7f-477e-b5bc-fbb8059c1dec')]
dfA = pd.DataFrame(A)

result = pd.DataFrame(columns=['A','month'])
for i in dfA.index:
    newdf = pd.DataFrame(index=benefit.index)
    newdf['A'] = dfA.iloc[i,0]
    newdf['month'] = newdf.index
    result = pd.concat([result,newdf])
result

你可以使用np.meshgrid

pd.DataFrame(np.array(np.meshgrid(dfA, dfB, )).T.reshape(-1, 2))

    0  1
0   a  1
1   a  2
2   a  3
3   a  4
4   b  1
5   b  2
6   b  3
7   b  4
8   c  1
9   c  2
10  c  3
11  c  4

在長度為300400 DataFrame對象上分別獲得大約~2000x加速:

A = ['a', 'b', 'c'] * 100
B = [1, 2, 3, 4] * 100

dfA = pd.DataFrame(A)
dfB = pd.DataFrame(B)

np.meshgrid

%%timeit
pd.DataFrame(np.array(np.meshgrid(dfA, dfB, )).T.reshape(-1, 2))
100 loops, best of 3: 8.45 ms per loop

vs cross

%timeit cross(dfA, dfB)
1 loop, best of 3: 16.3 s per loop

因此,如果我正確理解您的示例,您可以:

A = ['a', 'b', 'c']
dfA = pd.DataFrame(A)

start = datetime(year=2016, month=1, day=1)
end = datetime(year=2016, month=4, day=1)
months = pd.DatetimeIndex(start=start, end=end, freq="MS")
dfB = pd.DataFrame(months.month)

pd.DataFrame(np.array(np.meshgrid(dfA, dfB, )).T.reshape(-1, 2))

還得到:

    0  1
0   a  1
1   a  2
2   a  3
3   a  4
4   b  1
5   b  2
6   b  3
7   b  4
8   c  1
9   c  2
10  c  3
11  c  4

另外

a = [1,2,3]
b = ['a','b','c']
x,y = zip(*[i for i in zip(np.tile(a,len(a)),np.tile(b,len(a)))])
pd.DataFrame({'x':x,'y':y})

輸出:

    x   y
0   1   a
1   2   b
2   3   c
3   1   a
4   2   b
5   3   c
6   1   a
7   2   b
8   3   c

%%timeit
1000 loops, best of 3: 559 µs per loop

編輯:你實際上並不需要np.tile 一個簡單的理解就可以了

x,y = zip(*[(i,j) for i in a for j in b])

使用itertools.product

from itertools import product

result = pd.DataFrame(list(product(dfA.iloc[:,0], dfB.iloc[:,0])))

不如np.meshgrid有效,但它比其他解決方案更有效。

一種班輪方法

pd.DataFrame(0, A, B).stack().index.to_series().apply(pd.Series).reset_index(drop=True)

要么:

pd.MultiIndex.from_product([A, B]).to_series().apply(pd.Series).reset_index(drop=True)

從數據幀開始,假設信息在第一列中。

pd.MultiIndex.from_product([dfA.iloc[:, 0], dfB.iloc[:, 0]]).to_series().apply(pd.Series).reset_index(drop=True)

功能:

def cross(df1, df2):
    s1 = df1.iloc[:, 0]
    s2 = df2.iloc[:, 0]
    midx = pd.MultiIndex.from_product([s1, s2])
    df = midx.to_series().apply(pd.Series).reset_index(drop=True)
    df.columns = [s1.name, s2.name if s1.name != s2.name else 1]
    return df

print cross(dfA, dfB)

    0  1
0   a  1
1   a  2
2   a  3
3   a  4
4   b  1
5   b  2
6   b  3
7   b  4
8   c  1
9   c  2
10  c  3
11  c  4

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM