파이썬 3으로 작성된 내 프로그램에는 (매우 큰) 테이블 형 숫자 데이터 구조로 시작하여 특정 열에 따라 열을 추가하는 곳이 많이 있습니다 연산. (알고리즘은 모든 장소에서 다름)테이블을 순수 함수로 "확장하는"명령형 알고리즘 변환
나는 명령형 접근법으로 어려움을 겪고 있기 때문에 이것을 순수한 기능적 접근으로 변환하려고 노력하고있다. (재사용하기 어렵고, 중간 단계를 암기하기 어렵고, "게으른" 계산, 버그에 취약한 상태 의존 등).
Table
클래스는 사전 사전으로 구현됩니다. 외부 사전에는 row_id
으로 인덱싱 된 행이 포함됩니다. 내부는 column_title
에 의해 색인화 된 행의 값을 포함합니다. 테이블의 방법은 매우 간단하다 :
# return the value at the specified row_id, column_title
get_value(self, row_id, column_title)
# return the inner dictionary representing row given by row_id
get_row(self, row_id)
# add a column new_column_title, defined by func
# func signature must be: take a row and return a value
add_column(self, new_column_title, func)
지금까지, 나는 단순히 원래의 테이블에 열을 추가하고, 각 함수는 인수로 전체 테이블을했다. 필자가 순수 함수로 이동하면서 모든 인수를 변경하지 않아야합니다. 따라서 초기 표는 변경되지 않습니다. 추가 컬럼은 독립형 컬럼으로 작성되어이를 필요로하는 함수에만 전달됩니다. 일반적인 함수는 초기 테이블과 이미 생성 된 몇 개의 컬럼을 취해서 새로운 컬럼을 리턴합니다.
내가 만난 문제는 독립 실행 형 컬럼 (Column
)을 구현하는 방법입니까?
나는 그들 각각을 사전으로 만들 수 있지만, 매우 비싸 보입니다. 실제로 논리적 행마다 10 개의 필드를 조작해야하는 경우 10 개의 사전 조회가 필요합니다. 그리고 그 위에는 각 열에 키와 값이 포함되어 크기가 두 배로됩니다.
Column
을 간단한 목록으로 만들고 row_id에서 배열 색인으로의 매핑에 대한 참조를 저장할 수 있습니다. 이 맵핑은 동일한 초기 테이블에 해당하는 모든 C 럼간에 공유 될 수 있고 한 번 조회되면 모든 C 럼에서 작동한다는 이점이 있습니다. 그러나 이것으로 다른 문제가 발생합니까?
이렇게하면 초기 테이블 자체에 실제로 매핑을 저장할 수 있습니까? Column
개체의 참조를 만든 초기 테이블로 되돌릴 수 있습니까? 기능적 접근 방식을 상상했던 것과는 아주 다른 것처럼 보입니다. 그러나 모든 것이 불변하기 때문에 어떤 문제가 발생하는지 알 수 없습니다.
일반적으로 반환 값의 참조를 인수 중 하나에 유지하는 기능적 접근 방법은 싫은가요? 논쟁이 이미 어쨌든 알려 졌기 때문에 (최적화 나 게으른 평가와 같은) 어떤 것도 망가뜨릴 것 같지 않습니다. 하지만 어쩌면 내가 뭔가를 놓친 것 같아. 여기
너피 얼 (Numpy) 배열 사용에 대해 생각해 보셨습니까? 이는 마치 Numpy가 처리하도록 설계된 것과 같습니다. 특정 열이나 행에 액세스하여 인수로 전달하기가 쉽고 특히 순수 숫자 작업의 경우 매우 빠릅니다. –
'numpy.array'는 훌륭하게 작동합니다; 'pandas.DataFrame'도 훨씬 좋습니다. 그러나 유감스럽게도 필자가 설명한 이유 때문에 순수한 함수로 옮기고 싶습니다. 그리고 이것은 불변성을 필요로하기 때문에 새로 계산 된 열을 추가하여 원본 테이블을 확장 할 수는 없습니다. – max
함수형을 벗어나지 않고 Numpy 배열을 받아들이고 치수 (단일 열, 전체 테이블 ...)를 받아들이는 함수를 작성할 수 있습니다. IMO,'ndarray' 타입의 가변성은 여기에서도 존재하지도 않습니다. 함수에 부작용이 없도록해야합니다. 당신이 변이성을 사용하고 싶지 않다면, 그렇게하십시오. –