Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何展平每行数据帧?_Python_Pandas - Fatal编程技术网

Python 如何展平每行数据帧?

Python 如何展平每行数据帧?,python,pandas,Python,Pandas,我有一个熊猫数据框 state action reward absorb 0 [1.0, 2.0, 0.0, 0.0, 0.0, 0.0] 0.0 0.0 False 1 [0.0, 0.0, 4.0, 4.0, 5.0, 0.0] 3.0 1.0 False 2 [0.0, 0.0, 0.0, 2.0, 0.0, 1.0] 5.0 1.0 False 我想

我有一个熊猫数据框

                             state  action  reward  absorb
0   [1.0, 2.0, 0.0, 0.0, 0.0, 0.0]     0.0     0.0   False
1   [0.0, 0.0, 4.0, 4.0, 5.0, 0.0]     3.0     1.0   False
2   [0.0, 0.0, 0.0, 2.0, 0.0, 1.0]     5.0     1.0   False

我想把这个数据帧转换成

    s1  s2  s3  s4  s5  s6  action  reward
0  1.0 2.0 0.0 0.0 0.0 0.0     0.0     0.0
1  0.0 0.0 4.0 4.0 5.0 0.0     3.0     1.0

我将第一列分解为几列。我怎么能轻松做到这一点


谢谢大家!

为避免使用
应用
(对于大数据帧可能会很慢):

基准: 在中等大小的数据帧上,您将看到一些与
apply
相反的大时间改进。我还通过@piRSquared(在评论中)添加了另外两个矢量化解决方案进行比较

# Create a dataframe of 1000 values

df = pd.DataFrame({'state':np.random.choice(df.state.values, size = 1000),
                   'action': np.random.randint(0,10,1000),
                   'reward': np.random.randint(0,10,1000),
                   'absorb': np.random.choice([True, False, 1000])})

>>> df.head()
   absorb  action  reward                           state
0       1       6       8  [0.0, 0.0, 0.0, 2.0, 0.0, 1.0]
1       1       3       2  [0.0, 0.0, 4.0, 4.0, 5.0, 0.0]
2       1       8       3  [1.0, 2.0, 0.0, 0.0, 0.0, 0.0]
3       1       4       2  [0.0, 0.0, 0.0, 2.0, 0.0, 1.0]
4       1       6       3  [0.0, 0.0, 4.0, 4.0, 5.0, 0.0]

def concat_method(df1 = df.copy()):
    return pd.concat([df1[['action', 'reward', 'absorb']],
                    pd.DataFrame(df1.state.tolist(),
                                 columns = [f's{i}' for i in range(1,7)])],
                   axis=1)


def apply_method(df1 = df.copy()):
    df1[['s1', 's2','s3', 's4','s5', 's6']] = df1['state'].apply(pd.Series)
    return df1

def piR_method(df1 = df.copy()):
    return df1.assign(**dict((f"s{i}", z) for i, z in enumerate(zip(*df1.state)))).drop('state', 1)

def piR_method2(df1 = df.copy()):
    return df1.drop('state', 1).join(pd.DataFrame(df1.state.tolist(), df1.index).rename(columns=lambda x: f"s{x + 1}"))

def pir3(df=df):
    mask = df.columns.values != 'state'
    vals = df.values
    state = vals[:, np.flatnonzero(~mask)[0]].tolist()
    other = vals[:, mask]
    newv = np.column_stack([other, state])
    cols = df.columns.values[mask].tolist()
    sss = [f"s{i}" for i in range(1, max(map(len, state)) + 1)]

    return pd.DataFrame(newv, df.index, cols + sss)


import timeit

>>> timeit.timeit(concat_method, number = 100) / 100
0.0020290906500304118
>>> timeit.timeit(apply_method, number = 100) / 100
0.19950388665980426
>>> timeit.timeit(piR_method, number = 100) / 100
0.003522267839871347
>>> timeit.timeit(piR_method2, number = 100) / 100
0.002374379680259153
>>> timeit.timeit(pir3, number = 100)
0.17464107400155626

要避免使用
apply
(对于大数据帧,这可能会很慢):

基准: 在中等大小的数据帧上,您将看到一些与
apply
相反的大时间改进。我还通过@piRSquared(在评论中)添加了另外两个矢量化解决方案进行比较

# Create a dataframe of 1000 values

df = pd.DataFrame({'state':np.random.choice(df.state.values, size = 1000),
                   'action': np.random.randint(0,10,1000),
                   'reward': np.random.randint(0,10,1000),
                   'absorb': np.random.choice([True, False, 1000])})

>>> df.head()
   absorb  action  reward                           state
0       1       6       8  [0.0, 0.0, 0.0, 2.0, 0.0, 1.0]
1       1       3       2  [0.0, 0.0, 4.0, 4.0, 5.0, 0.0]
2       1       8       3  [1.0, 2.0, 0.0, 0.0, 0.0, 0.0]
3       1       4       2  [0.0, 0.0, 0.0, 2.0, 0.0, 1.0]
4       1       6       3  [0.0, 0.0, 4.0, 4.0, 5.0, 0.0]

def concat_method(df1 = df.copy()):
    return pd.concat([df1[['action', 'reward', 'absorb']],
                    pd.DataFrame(df1.state.tolist(),
                                 columns = [f's{i}' for i in range(1,7)])],
                   axis=1)


def apply_method(df1 = df.copy()):
    df1[['s1', 's2','s3', 's4','s5', 's6']] = df1['state'].apply(pd.Series)
    return df1

def piR_method(df1 = df.copy()):
    return df1.assign(**dict((f"s{i}", z) for i, z in enumerate(zip(*df1.state)))).drop('state', 1)

def piR_method2(df1 = df.copy()):
    return df1.drop('state', 1).join(pd.DataFrame(df1.state.tolist(), df1.index).rename(columns=lambda x: f"s{x + 1}"))

def pir3(df=df):
    mask = df.columns.values != 'state'
    vals = df.values
    state = vals[:, np.flatnonzero(~mask)[0]].tolist()
    other = vals[:, mask]
    newv = np.column_stack([other, state])
    cols = df.columns.values[mask].tolist()
    sss = [f"s{i}" for i in range(1, max(map(len, state)) + 1)]

    return pd.DataFrame(newv, df.index, cols + sss)


import timeit

>>> timeit.timeit(concat_method, number = 100) / 100
0.0020290906500304118
>>> timeit.timeit(apply_method, number = 100) / 100
0.19950388665980426
>>> timeit.timeit(piR_method, number = 100) / 100
0.003522267839871347
>>> timeit.timeit(piR_method2, number = 100) / 100
0.002374379680259153
>>> timeit.timeit(pir3, number = 100)
0.17464107400155626

使用
df['s1'、's2'、's3'、's4'、's5'、's6']=df['state']。应用(pd.Series)
。这不是很容易。所有的清单都一样长吗?如果不是的话,你期望它们的位置是什么?列表都是相同的长度。使用
df[['s1','s2','s3','s4','s5','s6']=df['state']。应用(pd.Series)
。这不是很容易。所有的清单都一样长吗?如果不是的话,你期望他们的位置是什么?列表都一样长。嗯,我不能测试,但我认为
contat
比apply@roganjosh不太可能,因为
apply
基本上是逐行迭代。请看我编辑的答案中的基准。这让我感到惊讶。试试这个
df.assign(**dict((f“s{i}),z)for i,z in enumerate(zip(*df.state),1)).drop('state',1)
df.drop('state',1).join(pd.DataFrame(df.state.tolist(),df.index).重命名(columns=lambda x:f“s{x+1”)
这只是你的一个变体。嗯,我无法测试,但我认为
contat
比apply@roganjosh不太可能,因为
apply
基本上是逐行迭代。请看我编辑的答案中的基准。这让我感到惊讶。试试这个
df.assign(**dict((f“s{i}),z)for i,z in enumerate(zip(*df.state),1)))。drop('state',1)
df.drop('state',1)。join(pd.DataFrame(df.state.tolist(),df.index)。重命名(columns=lambda x:f“s{x+1”)
这只是您的一个变体。