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

Python 如何更快、优雅地将一些逻辑应用于数据帧列

Python 如何更快、优雅地将一些逻辑应用于数据帧列,python,pandas,performance,dataframe,iterator,Python,Pandas,Performance,Dataframe,Iterator,我正在阅读一个包含许多列的csv文件,其中一列是TOD(一天中的时间)。有些活动超过了午夜,而不是回到00:00,而是持续增加到24:00。例如23:59:50,24:00:01,24:00:10,…) EntryTOD被解析为字符串 我想应用一个简单的逻辑,时间大于24,只需减去24小时。这是我的代码: for row in f2.itertuples(): # Fix times > 24h if int(row.EntryTOD[0:2]) >= 24:

我正在阅读一个包含许多列的csv文件,其中一列是TOD(一天中的时间)。有些活动超过了午夜,而不是回到00:00,而是持续增加到24:00。例如23:59:50,24:00:01,24:00:10,…) EntryTOD被解析为字符串

我想应用一个简单的逻辑,时间大于24,只需减去24小时。这是我的代码:

for row in f2.itertuples():
    # Fix times > 24h
    if int(row.EntryTOD[0:2]) >= 24:
        actualTime =  int(row.EntryTOD[0:2]) - 24
        f2.EntryTOD[row.Index-1] = str(actualTime) + row.EntryTOD[2:]
这段代码可以工作,但对于80k+行来说有点慢。运行大约需要30-40秒

我的问题是:

1) 有没有更快的方法

2) 另外,由于我对Python不是很在行,有没有更优雅的方法?它可能仍然需要遍历整个列,但我觉得这可以在一行代码中完成

提前谢谢大家,

圭多

解决方案: 感谢雷内:

f2.EntryTOD = f2.EntryTOD.apply(lambda x: str(int(x.split(':')[0])-24)+x[2:] if int(x.split(':')[0]) > 23 else x)

这是一个非常快的单班轮

我想这就是你想要的:

# Sample df
data = [
    ['25:22:22', 1, 5],
    ['01:01:01', 36, 2]
]
cols = ['EntryTOD', 'two', 'three']

df = pd.DataFrame(data, columns = cols)
df

    EntryTOD    two three
0   25:22:22    1   5
1   01:01:01    36  2
解决方案:

df['hour'] = (df['EntryTOD'].str[0:2]).astype(int)

df.loc[
    df.hour >= 24, 'hour'
] = df.loc[df.hour >= 24, 'hour'] - 24

# Edit EntryTOD variable
for i in range(df.shape[0]):
    df.EntryTOD.iloc[i] = df.EntryTOD.iloc[i].replace(
        df['EntryTOD'].str[0:2].iloc[i], '0'+df['hour'].astype(str).iloc[i]
    )
输出:

    EntryTOD    two three   hour
0   01:22:22    1    5      1
1   01:01:01    36   2      1
您可以尝试:

f2 = pd.DataFrame(['23:59', '23:59:59', '24:00', '24:01', '25:25:25'], columns=['TOD'])
f2.TOD.apply(lambda x: f"{int(x.split(':')[0])-24}:{x.split(':')[1]}" if int(x.split(':')[0]) > 23 else x)
结果:

0       23:59
1    23:59:59
2        0:00
3        0:01
4        1:25
Name: TOD, dtype: object

太棒了,我想我们很接近了。由于某些原因,它不起作用。这不是更紧凑吗:f2.EntryTOD.apply(lambda x:str(int(x.split(':')[0])-24)+x[2:]如果int(x.split(':')[0])>23 else x)我用一些打印测试了逻辑,它可以工作。f2.EntryTOD只是没有得到更新…这是有效的:f2.EntryTOD=f2.EntryTOD.apply(lambda x:str(int(x.split(“:”)[0])-24)+x[2:]如果int(x.split(“:”)[0])>23其他x)