我正在处理具有~(100000, 50)形状的熊猫数据格式,虽然我可以实现所需的数据格式和操作,但我发现我的代码运行所需的时间比预期的长(3-10分钟),这取决于具体任务,包括:
将来我将拥有更大的数据帧,并希望确保使用适当的编码方法来避免非常长的处理时间。我发现我的for循环花的时间最长。我试图避免使用列表理解和系列操作符(例如,for )来避免df.loc[:,'C'] = df.A + df.B循环,但在某些情况下,我需要使用嵌套的for循环执行更复杂/涉及更多的操作。例如,下面的代码遍历数据的系列history (一系列列表),然后遍历每个list中的每一项
for row in DF.iterrows():
removelist = []
for i in xrange(0, len(row[1]['history'])-1):
if ((row[1]['history'][i]['title'] == row[1]['history'][i+1]['title']) &
(row[1]['history'][i]['dept'] == row[1]['history'][i+1]['dept']) &
(row[1]['history'][i]['office'] == row[1]['history'][i+1]['office']) &
(row[1]['history'][i]['employment'] == row[1]['history'][i+1]['employment'])):
removelist.append(i)
newlist = [v for i, v in enumerate(row[1]['history']) if i not in removelist]我知道列表理解可以容纳嵌套的for循环,但在列表理解中,上面的内容看起来确实很麻烦。
我的问题:,我还可以使用哪些其他技术来实现与for循环相同的功能,并且处理时间更短?在迭代包含列表的系列时,是否应该使用嵌套for循环以外的其他技术?
发布于 2016-09-12 14:14:40
所以,这里似乎有一个数据,其中每一行的历史条目都包含一个字典列表?比如:
import pandas as pd
john_history = [{'title': 'a', 'dept': 'cs'}, {'title': 'cj', 'dept': 'sales'}]
john_history
jill_history = [{'title': 'boss', 'dept': 'cs'}, {'title': 'boss', 'dept': 'cs'}, {'title': 'junior', 'dept': 'cs'}]
jill_history
df = pd.DataFrame({'history': [john_history, jill_history],
'firstname': ['john', 'jill']})我会对您的数据进行重构,以便您在结构的底层使用熊猫结构,例如,在DataFrames中,每个DataFrame都是历史记录(我认为DataFrames在这里不起作用,因为DataFrames可能有不同的长度):
john_history = pd.DataFrame({'title': ['a', 'cj'], 'dept': ['cs', 'sales']})
john_history['name'] = 'john'
jill_history = pd.DataFrame({'title': ['boss', 'boss', 'junior'], 'dept': ['cs', 'cs', 'cs']})
jill_history['name'] = 'jill'
people = pd.concat([john_history, jill_history])然后,您可以使用groupby类来处理它们:
people.groupby('name').apply(pd.DataFrame.drop_duplicates)通常,如果您无法在熊猫/numpy中找到您想要的功能,您应该会发现使用熊猫原语来创建它,而不是迭代数据文件将会更快。例如,要重新创建上面的逻辑,首先创建一个新的dataframe,它是第一个移位的:
df2 = df.shift()现在,您可以通过比较dataframe的内容来创建一个选择,并且只保留不同的内容,并使用这些内容过滤数据:
selection_array = (df.history == df2.history) & (df.title == df2.title)
unduplicated_consecutive = df[~selection_array]
print(unduplicated_consecutive)
history id title
0 a 1 x
1 b 2 y
# or in one line:
df[~((df.history == df2.history) & (df.title == df2.title))]
# or:
df[(df.history != df2.history) | (df.title != df2.title)]所以把这个放到组里:
def drop_consecutive_duplicates(df):
df2 = df.shift()
return df.drop(df[(df.dept == df2.dept) & (df.title == df2.title)].index)
people.groupby('name').apply(drop_consecutive_duplicates)https://stackoverflow.com/questions/39452097
复制相似问题