我有一个大约9000的数据集,地区范围为1-5,10-99,100-115。我希望将数据和行扩展为所提供的数据集中的形式。
我的第一个想法可能是遍历序列'Terri‘并通过pd.series(range(i,100))运行它,但这不会产生下面的输出。
感谢你的帮助。
import pandas as pd
d={'Peril':['Fire','Wind'],'Terri':[1-5,6-10],'Premium':[100,200]}
output={'Peril':['Fire','Fire','Fire','Fire','Fire','Wind','Wind','Wind','Wind','Wind'],'Terri':[1,2,3,4,5,6,7,8,9,10],'Premium':[100,100,100,100,100,200,200,200,200,200]}
df=pd.DataFrame(data=d)
expected_output=pd.DataFrame(data=output)发布于 2019-04-20 00:35:13
使用几个助手列表理解,然后使用pandas.index.repeat、DataFrame.assign和numpy.hstack
import numpy as np
import pandas as pd
ranges = [np.arange(s, e+1) for s, e in [list(map(int, x)) for x in df.Terri.str.split('-')]]
lens = [len(x) for x in ranges]
df_new = df.loc[df.index.repeat(lens)].assign(Terri=np.hstack(ranges))输出
Peril Terri Premium
0 Fire 1 100
0 Fire 2 100
0 Fire 3 100
0 Fire 4 100
0 Fire 5 100
1 Wind 6 200
1 Wind 7 200
1 Wind 8 200
1 Wind 9 200
1 Wind 10 200作为参考,ranges如下所示:
[array([1, 2, 3, 4, 5]), array([ 6, 7, 8, 9, 10])]lens看起来像这样:
[5, 5]发布于 2019-04-20 00:31:05
假设Terri旨在包含字符串范围,而不是减法操作,您可以创建范围的DataFrame,然后使用stack来受益于对公共索引的joining,以扩展原始框架。
u = df['Terri'].str.split('-', expand=True).astype(int).values
j = pd.DataFrame(
[np.arange(start, stop+1) for start, stop in u]
)
j.stack().reset_index(1, drop=True).to_frame('Terri')
df.drop('Terri', 1).join(f)
Peril Premium Terri
0 Fire 100 1
0 Fire 100 2
0 Fire 100 3
0 Fire 100 4
0 Fire 100 5
1 Wind 200 6
1 Wind 200 7
1 Wind 200 8
1 Wind 200 9
1 Wind 200 10由于stack的行为将删除空值,因此您的范围不必是统一的长度。
发布于 2019-04-20 00:37:37
唯一有效的方法是,如果你开始的DataFrame的Terri列是一个字符串:
d={'Peril':['Fire','Wind'],'Terri':['1-5','6-10'],'Premium':[100,200]}
df = pd.DataFrame(d)
print(df)
# Peril Terri Premium
#0 Fire 1-5 100
#1 Wind 6-10 200如果在-上拆分Terri列中的字符串,则可以将其用作range的输入,除非需要向stop值添加1才能包括端点。为了方便起见,您可以定义自己的范围函数:
def myRange(a, b):
return range(a, b+1)现在,您可以拆分列,应用myRange函数,然后堆叠结果:
temp = pd.DataFrame(
df['Terri'].str.split("-")\
.apply(lambda x: pd.Series(myRange(*map(int, x))))\
.stack()\
.reset_index(level=1, drop=True),
columns=["Terri"]
)
print(temp)
# Terri
#0 1
#0 2
#0 3
#0 4
#0 5
#1 6
#1 7
#1 8
#1 9
#1 10最后,将此结果与原始DataFrame连接起来:
print(df.drop(["Terri"], axis=1).join(temp))
# Peril Premium Terri
#0 Fire 100 1
#0 Fire 100 2
#0 Fire 100 3
#0 Fire 100 4
#0 Fire 100 5
#1 Wind 200 6
#1 Wind 200 7
#1 Wind 200 8
#1 Wind 200 9
#1 Wind 200 10同样的事情,简而言之:
df.drop(["Terri"], axis=1).join(
pd.DataFrame(
df['Terri'].str.split("-")\
.apply(lambda x: pd.Series(myRange(*map(int, x))))\
.stack()\
.reset_index(level=1, drop=True),
columns=["Terri"]
)
)https://stackoverflow.com/questions/55764452
复制相似问题