naoki1117
@naoki1117

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

streamlit.file_uploaderについて

解決したいこと

streamlitで複数のcsvファイルをst.file_uploaderでアップロードしようとしていますが、一部のファイルのアップロードが止まったままになってしまい、うまくいかない。
止まったアップロードを☓で削除すると先に進む。
全てのアップロードがうまくいくようにしたいです。

該当するソースコードスクリーンショット 2024-01-23 122757.png

import streamlit as st
import pandas as pd
from io import BytesIO

# @st.cache_data(show_spinner=False)  # st.cache_dataを使用する
def generate_csv_data(dataframe):
    # データフレームをCSV形式のバイトデータに変換
    csv_data = dataframe.to_csv(index=False, encoding="utf-8-sig").encode("utf-8-sig")
    return csv_data


def dl_dataframe(dataframe):
    # ダウンロードボタンを表示
    st.download_button(
        label="ダウンロード",
        data=generate_csv_data(dataframe),
        file_name="downloaded_dataframe.csv",
        key="download_button",
    )


st.title("CSV作成")

uploaded_files = st.file_uploader(
    label="ファイルインストール", type="csv", accept_multiple_files=True, key="file_uploader"
)
with st.spinner("ファイル読み込み中..."):
    if uploaded_files is not None:
        count = 0
        df_list = []

        # ファイルの非同期読み込み
        for uploaded_file in uploaded_files:
            try:
                # アップロードされたファイルの内容をPandasのデータフレームに読み込む
                df = pd.read_csv(
                    uploaded_file, encoding="cp932", sep=",", dtype={"項目A": str}
                )
                df_list.append(df)
                count += 1
            except Exception as e:
                st.write(f"CSVファイルの読み込みエラー: {e}")

        # 読み込んだ複数のデータフレームを結合する
        if df_list:
            combined_df = pd.concat(df_list, ignore_index=True)

            # 結合したデータフレームを表示
            st.dataframe(combined_df)

            # ダウンロードボタンを表示
            dl_dataframe(combined_df)

            # データフレームの統計情報の表示
            st.write("データフレームの統計情報:")
            st.write(combined_df.describe())

            # データフレームの加工(例: 列の選択)
            selected_columns = st.multiselect("表示する列を選択してください", combined_df.columns)
            if selected_columns:
                grouped_df = (
                    combined_df.groupby(selected_columns)[["項目B", "項目C", "項目D"]]
                    .sum()
                    .reset_index()
                )

                st.write("SUM集計")
                st.write(grouped_df)

自分で試したこと

chatgptやググったりしましたがうまくいきません。
逆に混乱してきましたのでご教授のほどよろしくお願いいたします。。。

0

2Answer

みた感じではおかしな箇所がないようです。

  1. st.file_uploader
  2. with st.spinner
  3. dl_dataframe(combined_df)
     st.download_button

順序と構成を変更してはどうでしょう。streamlitのSPAの問題か?csvの書式の問題と予測します。

改善案 

  1. from io import BytesIOの除去
  2. @st.cache_dataの除去、キャッシュ不要
  3. with st.spinnerの除去、後で実装のこと、特にあっても良い
  4. accept_multiple_files=TrueをFalseに変更、1ファイルにする。
  5. dl_dataframeを削除、st.download_buttonは書かない
  6. st.dataframeにて画面表示させる。
  7. st.download_buttonはif combined_df in locals():の中にに書く、with st.spinner全体の次

streamlitは処理順序が重要視されます。x,y,z=st.columns(3)を用いて、処理と表示を分離することをお奨めします。

0Like

HalHarada様

ご回答ありがとうございます!

一度アドバイスをもとに変更してみます。

0Like

Comments

  1. 私は上記のケースに遭遇していないのはUTF-8のみの違いかも。

    ドラッグ&ドロップも正常に機能し、dfを普通に表示できています。io.BytesIOが不要な点も高評価です。

  2. @naoki1117

    Questioner

    HalHarada様

    ありがとうございます。

    色々試してはみましたがダメでした...
    やはり複数アップロードを試みると一部のアップロードが止まってしまいます。

    一応読み込むCSVもネット上に落ちてるサンプルCSVとかで試しましたが同じ状況です。
    出来れば複数読込の実装にしたいのですが、accept_multiple_files = false にして一つ一つ処理して
    重ねていくしかなさそうですね...

Your answer might help someone💌