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

Python 基于表中另一列的增量

Python 基于表中另一列的增量,python,pandas,dataframe,Python,Pandas,Dataframe,我有两列:组和级别范围。每个“组”都有一个水果列表,每个“级别范围”都有类似“L1-L4”的级别范围 理想的结果是下图中的“水果”和“等级”列 因此,如果范围是“L2-L3”,则level列将为1行显示“2”,然后为下一行显示“3”。我还想将“组”列表中的每个项目添加到“水果”列中 任何帮助都将不胜感激!谢谢大家! 以下是我所做的工作: 我创建了两个helper列:“level\u repeat”和“grouping\u repeat”来帮助我复制必要的行 df['level_repeat']

我有两列:组和级别范围。每个“组”都有一个水果列表,每个“级别范围”都有类似“L1-L4”的级别范围

理想的结果是下图中的“水果”和“等级”列

因此,如果范围是“L2-L3”,则level列将为1行显示“2”,然后为下一行显示“3”。我还想将“组”列表中的每个项目添加到“水果”列中

任何帮助都将不胜感激!谢谢大家!

以下是我所做的工作:

我创建了两个helper列:“level\u repeat”和“grouping\u repeat”来帮助我复制必要的行

df['level_repeat'] = df['Level'].replace(['L1-L6', 'L1-L2', 'L1-L3', 'L4-L6', 'L3-L6', 'L2-L6'], [6, 2, 3, 2, 3, 4])

df['grouping_repeat'] = df['Group'].str.len()

df_new = pd.DataFrame([df.ix[idx] for idx in df.index
                        for _ in range(df.ix[idx]['level_repeat'])]).reset_index(drop=True)

df_new = pd.DataFrame([df_new.ix[idx] for idx in df_new.index
                        for _ in range(df_new.ix[idx]['grouping_repeat'])]).reset_index(drop=True)           

结果是,对于上面的示例,我将有10行,其中组有2个项目,级别范围跨越5个级别(2*5=10)。但是,在将数据插入“水果”和“级别”列时,我仍然需要帮助。

我真的不知道如何在不迭代数据帧的情况下执行此操作。也许有更好的解决办法,但我没有想到。无论如何:

res = []
for _, row in df.iterrows():
    group = row['Group']
    lv_range_str = row['Level Range']

    #change this line if the format of 'Level Range' changes
    lv_range = range(lv_range_str[1], lv_range_str[4] + 1)

    res += [
        {
            'Group': group,
            'Level Range': lv_range_str,
            'Fruit': fruit,
            'Level': level
        }
        for level in lv_range
        for fruit in group
    ]

res = pd.DataFrame(res)
只有当
级别范围
中的所有字符串的格式为
L{i}-L{j}
时,它才会起作用,否则需要更改
lv_范围的定义


如果您的数据集很大,则可能需要一些时间,尽管这里有一种方法,我会首先使用数字的范围从“级别范围”创建一列“级别列表”,因此对于“L2-L5”,列表将是[2,3,4,5]

df['level_list'] = (df['Level Range'].str.split('-',expand=True)
                     .stack().str[-1].unstack()
                     .apply(lambda x: range(int(x[0]),int(x[1])+1),1))
现在,使用itertools中的product和两列with list(Group和level_list),您可以创建新的dataframe:

from itertools import product
df_new = pd.DataFrame([ [ind, group, level_range, g, l] 
                        for ind, group, level_range, level_list 
                             in df[['Group','Level Range', 'level_list']].itertuples() 
                                   for l, g in product(level_list, group) ], 
                      columns = ['original_ind','Group', 'Level Range', 'Fruit','Level'])
输入相似

df=pd.DataFrame({'Group':[['Apple','Banana']],'Level Range':['L2-L5']})
,

df_new
的结果是:

   original_ind            Group Level Range   Fruit  Level
0             0  [Apple, Banana]       L2-L5   Apple      2
1             0  [Apple, Banana]       L2-L5  Banana      2
2             0  [Apple, Banana]       L2-L5   Apple      3
3             0  [Apple, Banana]       L2-L5  Banana      3
4             0  [Apple, Banana]       L2-L5   Apple      4
5             0  [Apple, Banana]       L2-L5  Banana      4
6             0  [Apple, Banana]       L2-L5   Apple      5
7             0  [Apple, Banana]       L2-L5  Banana      5

注意:如果您不关心原始索引,您可以删除列或不创建它

您需要从字符串
L1-L5
中提取范围作为
[1,2,3,4,5]
,并使用此列表和水果列表的产品
[Apple,Banana]
创建一个数据框

您可以使用
itertools.product
pd.MultiIndex.from\u product
进行此操作

在这里,我使用后者&一个helper函数来构建范围

def get_level_range(x):
    a, b = x.replace('L', '').split('-')
    return range(int(a), int(b)+1)

dframes = []
for _, x in df.iterrows():
    dframes.append(
        pd.DataFrame(
            index=pd.MultiIndex.from_product(
                [get_level_range(x['Level Range']), x.Group, 
                 [tuple(x.Group)], [x['Level Range']]], 
                names=['Level', 'Fruit', 'Group', 'Level Range']
            )
        ).reset_index()
    )

pd.concat(dframes)

# produces output:

   Level   Fruit            Group Level Range
0      1   Apple  (Apple, Banana)       L1-L5
1      1  Banana  (Apple, Banana)       L1-L5
2      2   Apple  (Apple, Banana)       L1-L5
3      2  Banana  (Apple, Banana)       L1-L5
4      3   Apple  (Apple, Banana)       L1-L5
5      3  Banana  (Apple, Banana)       L1-L5
6      4   Apple  (Apple, Banana)       L1-L5
7      4  Banana  (Apple, Banana)       L1-L5
8      5   Apple  (Apple, Banana)       L1-L5
9      5  Banana  (Apple, Banana)       L1-L5
需要注意的一点是,
Group
需要从
list
转换为
tuple
,因为list是不可散列的,因此不能用作索引元素。但如果需要,可以稍后将其转换回
列表
,如下所示:

out.Group = out.Group.apply(list)

你能发布一些你已经完成的工作代码吗?这样就可以清楚地知道遗漏了哪一步。