私はn-by-mPandas DataFrame df
は次のように定義されています(これが最善の方法ではないことはわかっています。実際のコードでやろうとしていることには意味がありますが、それはTMIになりますこの投稿では、このアプローチが私の特定のシナリオで機能するように、私の言葉を引用してください。)
>>> df = DataFrame(columns=['col1'])
>>> df.append(Series([None]), ignore_index=True)
>>> df
Empty DataFrame
Columns: [col1]
Index: []
次のように、このDataFrameのセルにリストを保存しました。
>>> df['column1'][0] = [1.23, 2.34]
>>> df
col1
0 [1, 2]
何らかの理由で、DataFrameはこのリストをリストではなく文字列として保存しました。
>>> df['column1'][0]
'[1.23, 2.34]'
2つの質問があります。
更新
私が使用していたDataFrameは保存され、CSV形式から読み込まれました。 この形式は、DataFrame自体ではなく、リストを文字列からリテラルに変換しました。
あなたが指摘したように、これは一般にpandas DataFramesを_.csv
_ファイルとして保存およびロードするときに起こります。これはテキスト形式です。
あなたの場合、これはリストオブジェクトが_.csv
_ファイルとして保存できる文字列表現を持っているために起こりました。 _.csv
_をロードすると、その文字列表現が生成されます。
実際のオブジェクトを保存したい場合は、DataFrame.to_pickle()
を使用する必要があります(注:オブジェクトはpickle可能でなければなりません!)。
2番目の質問に答えるには、 _ast.literal_eval
_ で元に戻すことができます:
_>>> from ast import literal_eval
>>> literal_eval('[1.23, 2.34]')
[1.23, 2.34]
_
この問題に出会ったばかりで、非常に簡単な解決策があります( pandas.eval() )。私はpandas 0.20.0を使用しています。
# SETUP
import pandas as pd
import io
csv = io.StringIO(u'''
id list
A1 [1,2]
A2 [3,4]
A3 [5,6]
''')
df = pd.read_csv(csv, delim_whitespace = True)
# TYPE CHECK <type 'str'>
print type(df.at[0, 'list'])
# MAIN CONVERSION
df['list'] = pd.eval(df['list'])
# TYPE CHECK <type 'list'>
print type(df.at[0, 'list'])
1)この動作を回避する方法があります。ここでlocを使用してください。
>>> import pandas as pd
>>> df = pd.DataFrame(columns=['column1'])
>>> df = df.append(pd.Series(data = {'column1':[None]}), ignore_index = True)
column1
0 [None]
>>> # Add list to index 0 in column1
>>> df.loc[0,'column1'] = [1.23, 2.34]
>>> print(df.loc[0, 'column1'])
[1.23, 2.34]
2)この文字列をリストに変換するPythonの方法。 (これはおそらく、使用しているDataFrameがCSV形式から保存およびロードされていたために必要なものです。これにはいくつかの解決策があります)。これはpshep123の回答に追加されたものです。
from ast import literal_eval
import pandas as pd
csv = io.StringIO(u'''
id list
A1 [1,2]
A2 [3,4]
A3 [5,6]
''')
df = pd.read_csv(csv, delim_whitespace = True)
# Output is a string
df.loc[0, 'list']
'[1,2]'
# Convert entire column to a list
df.loc[:,'list'] = df.loc[:,'list'].apply(lambda x: literal_eval(x))
# Output is a list
df.loc[0, 'list']
[1, 2]
同じ問題がありました。 df.to_csv()を使用してデータフレームリストの列をCSVファイルに保存すると、リストの列は文字列に変換されます。 [42、42、42]の代わりに「[42、42、42]」
アレックスの答えは正解で、_literal_eval
_を使用して文字列をリストに戻すことができます。このアプローチの問題は、追加のライブラリをインポートする必要があり、関数をデータフレームに適用またはマップする必要があることです。簡単な方法は、Pandasとして列をPython object(dtype)
df["col1"].astype('O')
OはPythonリストを含むオブジェクト。詳細情報 ここ に使用されます。空のリスト文字列を解析する場合、このメソッドは失敗することに注意してください: "]
または、関数を列に適用することもできます(これは整数用です):
_def stringToList(string):
# input format : "[42, 42, 42]" , note the spaces after the commas, in this case I have a list of integers
string = string[1:len(string)-1]
try:
if len(string) != 0:
tempList = string.split(", ")
newList = list(map(lambda x: int(x), tempList))
else:
newList = []
except:
newList = [-9999]
return(newList)
df["col1"] = df["col1"].apply(lambda x: stringToList(x))
_
参照のみ... pandasリストを文字列に変換しないでください。
In [29]: data2 = [{'a': [1, 5], 'b': 2}, {'a': 5, 'b': 10, 'c': 20}]
In [30]: df = pd.DataFrame(data2)
In [31]: df
Out[31]:
a b c
0 [1, 5] 2 NaN
1 5 10 20
In [32]: df['a'][0], type(df['a'][0])
Out[32]: ([1, 5], list)
In [33]: pd.__version__
Out[33]: '0.12.0'
pandas-df = pd.read_csv(df_name, converters={'column_name': eval})
これは、その列を文字列の代わりにpythonの対応するdtypeとして読み取ります。
私が使用した簡単なハックは、最初と最後の要素(str形式のリストブラケット)のインデックスを作成するラムダ関数を呼び出し、リスト要素をintに置き換える別のメソッドが続くsplitメソッドを呼び出します。
df['column1'] = df['column1'].apply(lambda x:x[1:-1].split(',')).apply(lambda x:[int(i) for i in x])