我有一个庞大的迁徙运动数据库,我写了一些脚本来获取有用的信息,但它真的很慢。我不是一个专业的程序员,正如你会看到的,我想知道如何使这个数据收集更有效。
首先,初始CSV数据库的结构如下:
1排=1人 年龄性City_start City_destination ..。 人1 人2 .
最后的数据库结构:
Balance\_2004 Balance\_2005 .... City1City2 ……
为了计算每个城市和年份的余额,我创建了一个函数,用于过滤初始数据库,以计算city_destination ( INs )中有多少个特定的城市,city_start中有多少行(OUTs),然后用一个简单的和将余额计算为INs:
# idb = initial database
# City1 = pre-existing in final database
def get_balance(city, df):
ins = idb.City_start[idb.City_start == City1].count()
outs = idb.City_destination[idb.City_destination == City1].count()
balance = ins - outs
return balance然后,我使用这个函数将熊猫应用到最终数据库中,如下所示:
# fdb = final database
fdb['Balance_2004'] = idb['City_start'].apply(get_balance, df=idb)这很好,结局是我需要的,我总共使用了42个应用函数来获得更具体的数据,比如每个性别、每个年龄组.但是为了了解这个过程有多慢,我在45分钟前启动了这个脚本(42个函数),现在还在运行。
有没有办法用一种更省时的方式做这件事呢?
提前感谢
发布于 2018-09-14 10:19:04
我认为需要cities与year和DataFrameGroupBy.size进行聚合,并通过unstack进行整形,然后通过sub减去,如果有必要,则转换为integer:
idb = pd.DataFrame([("a", "Chicago", "Chicago", 2018),
("b", "New York", "Chicago", 2018),
("c", "New York", "Chicago", 2017),
("d", "Houston", "LA", 2018)],
columns=["Name", "City_start", "City_destination", 'year'])
print (idb)
Name City_start City_destination year
0 a Chicago Chicago 2018
1 b New York Chicago 2018
2 c New York Chicago 2017
3 d Houston LA 2018
a1 = idb.groupby(["City_start", 'year']).size().unstack(fill_value=0)
a2 = idb.groupby(["City_destination", 'year']).size().unstack(fill_value=0)
idb = a1.sub(a2, fill_value=0).astype(int).add_prefix('Balance_')
print (idb)
year Balance_2017 Balance_2018
Chicago -1 -1
Houston 0 1
LA 0 -1
New York 1 1发布于 2018-09-14 10:20:47
通过按城市分组,只做一次这样的计算也许是有意义的:
def get_balance_all_cities(df):
df_diff = pd.DataFrame([df.groupby(["City_start"])["Name"].count(),
df.groupby(["City_destination"])["Name"].count()]).T
df_diff.columns = "start", "end"
df_diff[df_diff.isna()] = 0
return df_diff.start - df_diff.end下面是一些关于它的工作原理的例子:
>>> df = pd.DataFrame([("Person 1", "Chicago", "Chicago"), ("Person 2", "New York", "Chicago"), ("Person 3", "Houston", "New York")], columns=["Name", "City_start", "City_destination"])
>>> df
Name City_start City_destination
0 Person 1 Chicago Chicago
1 Person 2 New York Chicago
2 Person 3 Houston New York
>>> ins = df.groupby(["City_start"])["Name"].count()
City_start
Chicago 1
Houston 1
New York 1
Name: Name, dtype: int64
>>> outs = df.groupby(["City_end"])["Name"].count()
City_destination
Chicago 2
New York 1
Name: Name, dtype: int64
>>> df_diff = pd.DataFrame([ins, outs]).T
>>> df_diff.columns = "start", "end"
>>> df_diff[df_diff.isna()] = 0
>>> balance = df_diff.start - df_diff.end
Chicago -1.0
Houston 1.0
New York 0.0
dtype: float64最后的解决办法是与那些在结束或开始时没有人居住但在另一段时间里确实生活的城市打交道。
https://stackoverflow.com/questions/52329820
复制相似问题