簡體   English   中英

Pandas:按列中的觀察數量擴展DataFrame

[英]Pandas: expanding DataFrame by number of observations in column

Stata具有函數expand ,它將行添加到與特定列中的值對應的數據庫中。 例如:

我有:

df = pd.DataFrame({"A":[1, 2, 3], 
                   "B":[3,4,5]})

   A  B
0  1  3
1  2  4
2  3  5

我需要的:

df2 = pd.DataFrame({"A":[1, 2, 3, 2, 3, 3], 
                    "B":[3,4,5, 4, 5, 5]})

   A  B
0  1  3
1  2  4
2  3  5
3  2  4
4  3  5
6  3  5

df.loc [0,'A']中的值為1,因此沒有額外的行添加到DataFrame的末尾,因為B = 3只應該發生一次。

df.loc [1,'A']中的值為2,因此在DataFrame的末尾添加了一個觀察值,使B = 4的總出現次數為2。

df.loc [2,'A']中的值為3,因此將兩個觀察值添加到DataFrame的末尾,使得B = 5的總出現次數為3。

為了讓我開始,我已經仔細研究了以前的問題,但沒有運氣。 任何幫助表示贊賞。

有許多可能性,都是圍繞np.repeat

def using_reindex(df):
    return df.reindex(np.repeat(df.index, df['A'])).reset_index(drop=True)

def using_dictcomp(df):
    return  pd.DataFrame({col:np.repeat(df[col].values, df['A'], axis=0) 
                          for col in df})

def using_df_values(df):
    return pd.DataFrame(np.repeat(df.values, df['A'], axis=0), columns=df.columns)

def using_loc(df):
    return df.loc[np.repeat(df.index.values, df['A'])].reset_index(drop=True)

例如,

In [219]: df = pd.DataFrame({"A":[1, 2, 3], "B":[3,4,5]})
In [220]: df.reindex(np.repeat(df.index, df['A'])).reset_index(drop=True)
Out[220]: 
   A  B
0  1  3
1  2  4
2  2  4
3  3  5
4  3  5
5  3  5

這是1000行DataFrame的基准測試; 結果是一個大約500K行的DataFrame:

In [208]: df = make_dataframe(1000)

In [210]: %timeit using_dictcomp(df)
10 loops, best of 3: 23.6 ms per loop

In [218]: %timeit using_reindex(df)
10 loops, best of 3: 35.8 ms per loop

In [211]: %timeit using_df_values(df)
10 loops, best of 3: 31.3 ms per loop

In [212]: %timeit using_loc(df)
1 loop, best of 3: 275 ms per loop

這是我用來生成df的代碼:

import numpy as np
import pandas as pd

def make_dataframe(nrows=100):
    df = pd.DataFrame(
        {'A': np.arange(nrows),
         'float': np.random.randn(nrows),
         'str': np.random.choice('Lorem ipsum dolor sit'.split(), size=nrows),
         'datetime64': pd.date_range('20000101', periods=nrows)},
        index=pd.date_range('20000101', periods=nrows))
    return df

df = make_dataframe(1000)

如果只有幾列,則using_dictcomp是最快的。 但請注意, using_dictcomp假設df具有唯一的列名。 using_dictcomp的字典理解不會重復重復的列名。 但是,其他替代方法將使用重復的列名稱。

using_reindexusing_loc都假定df具有唯一索引。


using_reindex來自cᴏʟᴅsᴘᴇᴇᴅ的using_loc ,在一個(不幸的是)現已刪除的帖子中。 cᴏʟᴅsᴘᴇᴇᴅ表明沒有必要手動重復所有值 - 你只需要重復索引然后讓df.loc (或df.reindex )為你重復所有行。 它還避免訪問df.values ,如果df包含多個dtypes的列,則df.values可以生成object df.values的中間NumPy數組。

暫無
暫無

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

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