簡體   English   中英

使用python將文件存儲在不同的子目錄中

[英]Store files in different subdirectories using python

我有一個如下所示的 Pandas 數據框df

import pandas as pd
d = {'user': ['Peter', 'Peter', 'Peter', 'Peter', 'David', 'David', 'David', 'Emma', 'Joyce', 'Joyce', 'Joyce'], 'date': ['2019-03-04', '2019-03-04', '2019-03-04', '2019-03-04', '2019-03-04', '2019-03-04', '2019-03-04', '2019-03-04', '2019-03-04', '2019-03-04', '2019-03-04'], 'lat': [37.749798119650926, 37.751028173710736, 37.751698332490214, 37.75180012822952, 38.122893081890844, 38.124108467926035, 38.12743379574882, 37.89363489791644, 37.53620628385582, 37.53804390907164, 37.54044296272588], 'lon': [-122.49230146408082, -122.49229073524474, -122.49170064926147, -122.48974800109862, -122.24205136299133, -122.23907947540283, -122.23867177963257, -122.07653760910033, -121.99707984924316, -121.99315309524536, -121.9914150238037]}
df = pd.DataFrame(data=d)
df

user    date        lat         lon
Peter   2019-03-04  37.749798   -122.492301
Peter   2019-03-04  37.751028   -122.492291
Peter   2019-03-04  37.751698   -122.491701
Peter   2019-03-04  37.751800   -122.489748
David   2019-03-04  38.122893   -122.242051
David   2019-03-04  38.124108   -122.239079
David   2019-03-04  38.127434   -122.238672
Emma    2019-03-04  37.893635   -122.076538
Joyce   2019-03-04  37.536206   -121.997080
Joyce   2019-03-04  37.538044   -121.993153
Joyce   2019-03-04  37.540443   -121.991415

使用下面的代碼,我可以創建四個單獨的大葉地圖,按用戶分組,顯示地圖上的坐標。 四個地圖文件以用戶命名: Peter.htmlDavid.htmlEmma.htmlJoyce.html

import folium

users = list(df.user.unique())

def create_user_map(user):
    m = folium.Map(location=[37.733795, -122.446747], 
           zoom_start=9, 
           min_zoom=10, 
           max_zoom=19,
           control_scale=True)
 
    df_user = df[df.user==user]
    for row in df_user.itertuples():
         folium.CircleMarker( location=[row.lat, row.lon],
            radius=4,
            fill=True,
           fill_opacity=0.5).add_to(m)
    return m

for user in users:
    user_map = create_user_map(user)
    user_file = f"{user}.html"
    user_map.save(user_file)

現在我想根據下面的文件夾結構自動將這些文件存儲在相應的子目錄中。 我怎樣才能擴展上面的循環來實現這一點?

Report/
└── Report_per_date/ 
    ├── 2019-03-01/
    ├── 2019-03-02/
    ├── 2019-03-03/
    └── 2019-03-04/
         └── Users/
             └── Peter/
                 └── Peter.html
             └── David/
                 └── David.html
             └── Emma/
                 └── Emma.html
             └── Joyce/
                 └── Joyce.html

我希望我能做到這一點如下:

import os
rootdir = pathlib.Path('./Report')
report_per_date = df.apply(lambda x: rootdir / 'Report_per_date' / x['date'] / 'Users' / x['user'] / f"{x['user']}.html", axis='columns')

for mapfile, data in df.groupby(report_per_date):
    mapfile.parent.mkdir(parents=True, exist_ok=True)
    user_map = create_user_map(user)
    user_map.save(mapfile)

不幸的是,這返回了一個AttributeError: 'PosixPath' object has no attribute 'write'

我在我的機器上嘗試了代碼,遇到了類似的問題,但得到了AttributeError: 'WindowsPath' object has no attribute 'write'

看起來 Folium 使用模塊 branca 來保存到 HTML,並且看起來 branca 不能寫入路徑對象。 我可以通過將路徑轉換為字符串來修復它:

user_map.save(str(mapfile))

這解決了我機器上的問題,並且因為您在使用字符串之前讓 user_map.save() 工作,這也可能對您有用。

此外,在下面的代碼段中,您正在對變量 user 調用 create_user_map。

for mapfile, data in df.groupby(report_per_date):
    mapfile.parent.mkdir(parents=True, exist_ok=True)
    user_map = create_user_map(user)
    user_map.save(mapfile)

但是在這個例子中這將永遠是 Joyce,因為這是for user in users:for user in users:遺留下來的for user in users:上面的部分。 一個想法是從循環中的路徑中獲取用戶,如下所示:

for mapfile, data in df.groupby(report_per_date):
    mapfile.parent.mkdir(parents=True, exist_ok=True)
    user_map = create_user_map(mapfile.stem)
    user_map.save(str(mapfile))

這是有效的,因為 .stem 返回沒有擴展名的文件名。

您可以更改循環以包含日期,還可以在 df 中創建一個“路徑”列。

df['path'] = df.apply(lambda x: rootdir / 'Report_per_date' / x['date'] / 'Users' / x['user'] / f"{x['user']}.html",
                      axis='columns')

dates = list(df.date.unique())


def create_user_map(df_user):
    m = folium.Map(location=[37.733795, -122.446747], 
               zoom_start=9, 
               min_zoom=10, 
               max_zoom=19,
               control_scale=True)
 
    for row in df_user.itertuples():
          folium.CircleMarker( location=[row.lat, row.lon],
                radius=4,
                fill=True,
                fill_opacity=0.5).add_to(m )
     
    return m

for user in users:
    for date in dates:
        data = df[(df.user==user)&(df.date==date)]
        path = data.iloc[0]['path']        
        path.parent.mkdir(parents=True, exist_ok=True)            
        user_map = create_user_map(data)
        user_map.save(str(path))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM