Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/287.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_Numpy_Dataframe - Fatal编程技术网

Python 在大熊猫数据帧中将条目重新分配到多行

Python 在大熊猫数据帧中将条目重新分配到多行,python,pandas,numpy,dataframe,Python,Pandas,Numpy,Dataframe,我有一个数据帧(源自CSV文件),其中包含大约100万个条目,如下所示: df1: var1 var2 0 1 2 1 2 1 2 1 {3,4,5} 3 5 6 4 {4,5,6,7} 8 我需要将其转换为一个新的数据框,其中(对于每一行),大括号中的每个元素都需要与另一列中的元素相关联,即 df2: var1 var2 0

我有一个数据帧(源自CSV文件),其中包含大约100万个条目,如下所示:

df1:

        var1     var2
0          1        2
1          2        1
2          1  {3,4,5}
3          5        6
4  {4,5,6,7}        8
我需要将其转换为一个新的数据框,其中(对于每一行),大括号中的每个元素都需要与另一列中的元素相关联,即

df2:

  var1 var2
0    1    2
1    2    1
2    1    3
3    1    4
4    1    5
5    5    6
6    4    8
7    5    8
8    6    8
9    7    8
每个元素都是一个字符串,甚至是大括号条目本身。请注意,支撑图元可以位于任一列中。有人知道我如何才能有效地为大约1亿个条目的数据集实现这一点吗?提前谢谢

Python示例:

import pandas as pd

df1 = pd.DataFrame([{'var1': '1', 'var2': '2'},
               {'var1': '2', 'var2': '1'},
               {'var1': '1', 'var2': '{3,4,5}'},
               {'var1': '5', 'var2': '6'},
               {'var1': '{4,5,6,7}', 'var2': '8'}])


df2 = pd.DataFrame([{'var1': '1', 'var2': '2'},
               {'var1': '2', 'var2': '1'},
               {'var1': '1', 'var2': '3'},
               {'var1': '1', 'var2': '4'},
               {'var1': '1', 'var2': '5'},
               {'var1': '5', 'var2': '6'},
               {'var1': '4', 'var2': '8'},
               {'var1': '5', 'var2': '8'},
               {'var1': '6', 'var2': '8'},
               {'var1': '7', 'var2': '8'}])
到目前为止,我已经这样做了,但是速度很慢,并且使用了另一个数据帧

# Put row with braces in the second column
def swap_cols(row):
    if '{' in row[0]:
        return (row[1], row[0])
    return row

# Convert the braces into a list
def parse_str(s):
    if '{' in s:
        s = s[1:-1]
        return s.split(',')
    return [s]


df3 = df1.apply(swap_cols, axis=1)

df3.var2 = df3.var2.apply(parse_str)

# Show that it works
for ridx, row in df3.iterrows():
    for ele in row.var2:
        print row.var1, ele
你可以试试:

# isolate these cases as they will be treated separately
case1 = df1['var1'].str.contains('{')
case2 = df1['var2'].str.contains('}')

# convert to lists
import ast
df1 = df1.apply(lambda col: col.str.replace('{', '[').str.replace('}', ']')) \
         .applymap(ast.literal_eval)
在第二种情况下:

df1[case2].groupby('var1')['var2'].apply(lambda g: pd.Series(g.sum())) \
          .reset_index(-1, drop=True).reset_index()
应用
sum
将为
var1
的每个值连接列表(如果有多个),并将其转换为
pandas.Series
将给出您要查找的形状

然后可以将所有内容连接回:

pd.concat([
    df1[~case1 & ~case2],
    df1[case1].groupby('var2')['var1'].apply(lambda g: pd.Series(g.sum())).reset_index(-1, drop=True).reset_index(),
    df1[case2].groupby('var1')['var2'].apply(lambda g: pd.Series(g.sum())).reset_index(-1, drop=True).reset_index()
]).sort_values('var1')  # sorting optional
用于展平:

#create lists by remove {} and split
splitted1 = df1['var1'].str.strip('{}').str.split(',')
#get legths of lists
lens1 = splitted1.str.len()

splitted2 = pd.Series(np.repeat(df1['var2'].values, lens1)).str.strip('{}').str.split(',')
lens2 = splitted2.str.len()

df = pd.DataFrame({'a':np.repeat(np.concatenate(splitted1), lens2),
                   'b':np.concatenate(splitted2)})
print (df)
   a  b
0  1  2
1  2  1
2  1  3
3  1  4
4  1  5
5  5  6
6  4  8
7  5  8
8  6  8
9  7  8

您可以将
np.vstack
np.meshgrid
重塑
一起使用,即

sdf = df.apply(lambda x:(x.str.strip('{}').str.split(',')))

def cartesian(x): 
    return np.vstack(np.array([np.array(np.meshgrid(*i)).T.reshape(-1,2) for i in x.values]))

ndf = pd.DataFrame(cartesian(sdf),columns=sdf.columns)
如果要剥离和拆分,然后应用笛卡尔坐标

%%time 
100 loops, best of 3: 4 ms per loop
如果您确实有条带化和拆分的数据帧,则:

1000 loops, best of 3: 564 µs per loop
输出:

var1 var2 0 1 2 1 2 1 2 1 3 3 1 4 4 1 5 5 5 6 6 4 8 7 5 8 8 6 8 9 7 8 var1 var2 0 1 2 1 2 1 2 1 3 3 1 4 4 1 5 5 5 6 6 4 8 7 5 8 8 6 8 9 7 8
我添加了numpy标签,这可以吸引有趣的答案:)所以没有一个答案是有用的?我想看看现实生活中的性能比较。