Panda DataFrame은 다음 문자열로 목록을 저장했습니다.목록으로 다시 변환하는 방법
n-by-m Panda Data Frame을 가지고 있습니다.df
다음과 같이 정의됩니다.(이 방법이 최선책이 아니라는 것을 알고 있습니다.실제 코드로 무엇을 하려고 하는지는 이해가 되지만, 이 투고에서는 TMI가 되기 때문에, 이 어프로치는 특정의 시나리오에서 유효하게 됩니다).
>>> df = DataFrame(columns=['col1'])
>>> df.append(Series([None]), ignore_index=True)
>>> df
Empty DataFrame
Columns: [col1]
Index: []
저는 이 Data Frame의 셀에 다음과 같이 리스트를 저장했습니다.
>>> df['column1'][0] = [1.23, 2.34]
>>> df
col1
0 [1, 2]
어떤 이유로 DataFrame은 이 목록을 목록이 아닌 문자열로 저장했습니다.
>>> df['column1'][0]
'[1.23, 2.34]'
두 가지 질문이 있습니다.
- Data Frame은 왜 목록을 문자열로 저장하며 이 동작을 회피하는 방법이 있습니까?
- 그렇지 않다면 이 문자열을 목록으로 변환할 수 있는 피토닉 방법이 있습니까?
갱신하다
사용하던 Data Frame은 CSV 형식으로 저장 및 로딩되어 있었습니다.DataFrame 자체가 아닌 이 형식은 목록을 문자열에서 리터럴로 변환했습니다.
지적하신 바와 같이 팬더 DataFrames를 다음과 같이 저장하고 로드할 때 일반적으로 발생할 수 있습니다..csv
파일(텍스트 형식)을 지정합니다.
이 문제는 목록 객체에 문자열이 표시되므로 다음과 같이 저장할 수 있기 때문에 발생합니다..csv
파일 로드.csv
그러면 문자열이 표시됩니다.
실제 개체를 저장하려면 다음 명령을 사용해야 합니다.DataFrame.to_pickle()
(주의: 객체는 선택 가능해야 합니다!)
두 번째 질문에 답하려면 다음과 같이 다시 변환할 수 있습니다.
>>> from ast import literal_eval
>>> literal_eval('[1.23, 2.34]')
[1.23, 2.34]
판다를 직접 이용할 수 있다-
import pandas as pd
df = pd.read_csv(DF_NAME, converters={'COLUMN_NAME': pd.eval})
이 컬럼은 문자열 대신 python에서 대응하는 dtype으로 읽힙니다.
갱신:
@ctwardy가 댓글로 지적한 바와 같이.사용하는 것이 현명하다pd.eval
대신eval
의도하지 않은 regex 관련 결과를 방지하기 위해 사용됩니다.상세 - https://realpython.com/python-eval-function/ #security-of-valuation
- Python 리터럴 또는 컨테이너 데이터 형식을 포함하는 문자열을 안전하게 평가하는 데 사용합니다.
표준 라이브러리의 일부입니다.
python's eval() vs. ast.literal_eval()을 사용하면 그 이유를 알 수 있습니다.
literal_eval
사용하는 것보다 안전합니다.eval
.예:
literal_eval("[1.23, 2.34]")
작동하다literal_eval("['KB4523205','KB4519569','KB4503308']")
작동하다- 다른 답변에서는 를 언급하고 있습니다만, 그 사용법은 한정되어 있습니다.
ValueError: NumExpr 2 does not support Unicode as a dtype.
이 간단한 예시를 위해.
- 다른 답변에서는 를 언급하고 있습니다만, 그 사용법은 한정되어 있습니다.
literal_eval("[KB4523205, KB4519569, KB4503308]")
동작하지 않는다(주변에 견적 없음)str
값)- 판다 보기 - 이 표현을 다루기 위한 문자열 목록으로 문자열을 변환합니다.
- 는 열 변환하기 '열 변환'을 합니다.
converters
의 파라미터입니다.
의 test.csv
col1
"[1.23, 2.34]"
"['KB4523205','KB4519569','KB4503308']"
csv를 생성할 때 열 변환
from ast import literal_eval
import pandas as pd
# convert the column during import
df = pd.read_csv('test.csv', converters={'col1': literal_eval})
# display(df)
col1
0 [1.23, 2.34]
1 [KB4523205, KB4519569, KB4503308]
# check type
print(type(df.iloc[0, 0]))
list
print(type(df.iloc[1, 0]))
list
기존 데이터 프레임의 열을 변환합니다.
df.col1 = df.col1.apply(literal_eval)
%%timeit
pd.eval
literal_eval
- 의 「」
test.csv
의 2,820,511 의 with"[1.23, 2.34]"
방금 이 문제를 발견했는데 매우 간단한 해결책(pandas.eval())이 있습니다.팬더 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 help를 사용합니다.
>>> 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) 이 문자열을 목록으로 변환하는 피토닉 방식.(사용하는 Data Frame은 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_csvflist 목록을 사용하여 CSV 파일에 데이터 프레임목록 열을 저장하는 경우 [42, 42, 42]가 아닌 문자열로 변환됩니다.
이고 알렉스를 해도 됩니다.사용할 수 있습니다.literal_eval
이치노이 접근방식의 문제는 추가 라이브러리를 Import하고 함수를 데이터 프레임에 적용 또는 매핑해야 한다는 것입니다.보다 쉬운 방법은 Panda가 Python 객체로 칼럼을 읽도록 강제하는 것입니다(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))
참고용으로만...판다는 목록을 끈으로 바꾸지 않는다.
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'
제가 사용한 간단한 해킹은 lambda 함수를 호출하는 것입니다.이 함수는 처음과 마지막 요소(str 형식의 목록 괄호)를 인덱스 아웃하고 다음으로 분할 메서드를 호출한 후 목록 요소를 int로 대체하는 것입니다.
df['column1'] = df['column1'].apply(lambda x:x[1:-1].split(',')).apply(lambda x:[int(i) for i in x])
알렉스의 대답에 더해서.다음은 개별 항목을 문자열에서 목록으로 변환하는 데 사용할 수 있는 다른 버전입니다.
import pandas as pd
from ast import literal_eval
df = pd.read_csv("some_csvfile.csv")
def item_gen(l):
for i in l:
yield(i)
for i in item_gen(df["some_column_with_list_item"]):
print(literal_eval(i))
언급URL : https://stackoverflow.com/questions/23111990/pandas-dataframe-stored-list-as-string-how-to-convert-back-to-list
'programing' 카테고리의 다른 글
heroku 코드를 배포할 때 사용 권한이 거부되었습니다(공개 키).치명적: 리모트엔드가 예기치 않게 절단되었습니다. (0) | 2023.04.10 |
---|---|
2개의 리스트를 요소별로 곱하는 방법은 무엇입니까? (0) | 2023.04.10 |
Swift에서 두 날짜(월/일/시간/분/초)의 차이 파악 (0) | 2023.04.10 |
IEnumberable vs List - 사용방법그들은 어떻게 일하는가? (0) | 2023.04.10 |
Apple 프로덕션 푸시 SSL 인증서를 .p12 형식으로 내보낼 수 없습니다. (0) | 2023.04.10 |